spring aop分析(二)

三、计算拦截器链

    调用链图:


    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;
	}

  ...
}

猜你喜欢

转载自zhuhui-zj.iteye.com/blog/321114