三、计算拦截器链
调用链图:
JdkDynamicAopProxy实现了InvocationHandler接口,当其创建的JDK Proxy上的某一个方法被调用时,将会被JdkDynamicAopProxy类中的invoke(..)方法拦截:
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { ... try { ... target = targetSource.getTarget(); if (target != null) { targetClass = target.getClass(); } // 计算拦截器链 List chain = this.advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this.advised, proxy, method, targetClass); if (chain.isEmpty()) { // 拦截器链为空,直接调用目标对象上的方法 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); } else { // 调用方法 invocation = new ReflectiveMethodInvocation( proxy, target, method, args, targetClass, chain); retVal = invocation.proceed(); } ... return retVal; } finally { ... } } ... }
AdvisedSupport中AdvisorChainFactory的默认实现是HashMapCachingAdvisorChainFactory,它能将某一方法上的拦截器链进行缓存。
public final class HashMapCachingAdvisorChainFactory implements AdvisorChainFactory { public List getInterceptorsAndDynamicInterceptionAdvice( Advised config, Object proxy, Method method, Class targetClass) { private final Map methodCache = CollectionFactory.createIdentityMapIfPossible(32); List cached = (List) this.methodCache.get(method); if (cached == null) { // recalculate cached = AdvisorChainFactoryUtils.calculateInterceptorsAndDynamicInterceptionAdvice( config, proxy, method, targetClass); this.methodCache.put(method, cached); } return cached; } ... }
工具类AdvisorChainFactoryUtils提供了计算拦截器的方法:
public abstract class AdvisorChainFactoryUtils { public static List calculateInterceptorsAndDynamicInterceptionAdvice( Advised config, Object proxy, Method method, Class targetClass) { List interceptorList = new ArrayList(config.getAdvisors().length); ... AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); for (int i = 0; i < config.getAdvisors().length; i++) { //遍历每一个Advisor Advisor advisor = config.getAdvisors()[i]; if (advisor instanceof PointcutAdvisor) { // add it conditionally PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; // 计算该Advisor是否适合该class if (pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) { // 将advisor持有的before、after、throws等advice转化为统一 // 的MethodInterceptor Interceptor[] interceptors = registry.getInterceptors(advisor); MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); // 计算该Advisor是否适合该method if (methodMatches(mm,method, targetClass,hasIntroductions)) { if (mm.isRuntime()) { ... //动态interceptor } else { // 将该Advisor加入method的interceptor列表 interceptorList.addAll(Arrays.asList(interceptors)); } } } } else if (advisor instanceof IntroductionAdvisor) { ... } } return interceptorList; } ... }