|
public class WrapUtil implements InvocationHandler {
/* 目标对象 */ private Object target; /* 拦截器*/ private MyInterceptor interceptor; /* 要拦截的类 以及 对应的 方法*/ private Map, Set> signatureMap;
public WrapUtil(Object target, MyInterceptor interceptor,
Map, Set> signatureMap) { this.target = target; this.interceptor = interceptor; this.signatureMap = signatureMap;
}
/** * * @param target 代理前的对象 * @param interceptor 拦截器 * @return 代理后的对象 */ public static Object warp(Object target, MyInterceptor interceptor) { // 获取interceptor类要 拦截的类和方法 Map, Set> signatureMap = getSignatureMap(interceptor);
Class<?> type = target.getClass();
// 要拦截的对象及其父类 在 signatureMap 中,就统计 Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
if (interfaces.length > 0) { return Proxy.newProxyInstance(type.getClassLoader(), interfaces,
new WrapUtil(target, interceptor, signatureMap)); } return target;
}
/** * 获取type类及其父类 所有 在signatureMap 中的类 */ private static Class<?>[] getAllInterfaces(Class<?> type, Map, Set> signatureMap) {
Set> interfaces = new HashSet<>(); while (type != null) { for (Class<?> c : type.getInterfaces()) { if (signatureMap.containsKey(c)) { interfaces.add(c); } }
type = type.getSuperclass(); } return interfaces.toArray(new Class<?>[0]); }
private static Map, Set> getSignatureMap(MyInterceptor interceptor) { MyIntercepts interceptsAnnotation =
interceptor.getClass().getAnnotation(MyIntercepts.class); if (interceptsAnnotation == null) { throw new RuntimeException("拦截的方法必须加@MyIntercepts注解"); }
Signature[] sigs = interceptsAnnotation.value(); HashMap, Set> signatureMap = new HashMap<>(); for (Signature sig : sigs) { Set methods = signatureMap.computeIfAbsent(
sig.type(), k -> new HashSet<>()); Method method = null; try { method = sig.type().getMethod(sig.method(), sig.args()); methods.add(method); } catch (NoSuchMethodException e) { throw new RuntimeException("Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e, e); } } return signatureMap; }
/** * 调用代理后的对象的方法,都会走到这个方法 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 如果method所在类和method在signatureMap中,就执行拦截器的拦截方法 Set methods = signatureMap.get(method.getDeclaringClass()); if (methods != null && methods.contains(method)) { // 将参数封装到 MyInvocation中,传给拦截器 处理 return interceptor.intercept(new MyInvocation(target, method, args)); } // 要调用target原始对象,而不是proxy对象 return method.invoke(target, args); } }
|