无论基于JDK还是CGLib,在触发方法调用时都会先通过List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);这句代码去获取拦截链.其中advised是AdvisedSupport类型.下面看看这个方法:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) { MethodCacheKey cacheKey = new MethodCacheKey(method); List<Object> cached = this.methodCache.get(cacheKey); if (cached == null) { cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this, method, targetClass); this.methodCache.put(cacheKey, cached); } return cached; }MethodCacheKey的equals方法就是根据传进来的方法是否判断为同一个对象.private transient Map<MethodCacheKey, List<Object>> methodCache;很明显是一个map,作用是实现缓存.AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();可以知道是通过工厂去获取,DefaultAdvisorChainFactory是默认实现,当然可以注入自定义实现.再看org.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
public List<Object> getInterceptorsAndDynamicInterceptionAdvice( Advised config, Method method, Class<?> targetClass) { //使用一个List来装要获取的拦截器,最将返回这个拦截链 List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length); Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); //判断配置config是否符合要求 boolean hasIntroductions = hasMatchingIntroductions(config, actualClass); //通过单例方式实例一个DefaultAdvisorAdapterRegistry, AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); //从配置获取所有的Advisor进行迭代 for (Advisor advisor : config.getAdvisors()) { if (advisor instanceof PointcutAdvisor) { //如果是PointcutAdvisor类型 PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { //已预过滤过的或者这个切点适用于给定的接口或目标类 //从registry获取MethodInterceptor拦截器 MethodInterceptor[] interceptors = registry.getInterceptors(advisor); MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) { //如果切点的MethodMatcher都匹配这个method if (mm.isRuntime()) { //如果是动态MethodMatcher,就会对每一个interceptor创建一个新的InterceptorAndDynamicMethodMatcher拦截器,并加入到返回List. for (MethodInterceptor interceptor : interceptors) { interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); } } else { //不是动态的MethodMatcher,将所有的拦截器加入到返回List interceptorList.addAll(Arrays.asList(interceptors)); } } } } else if (advisor instanceof IntroductionAdvisor) { IntroductionAdvisor ia = (IntroductionAdvisor) advisor; if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } else { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } return interceptorList; }再看看org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#getInterceptors
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3); Advice advice = advisor.getAdvice(); if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor) advice); } for (AdvisorAdapter adapter : this.adapters) { if (adapter.supportsAdvice(advice)) { interceptors.add(adapter.getInterceptor(advisor)); } } if (interceptors.isEmpty()) { throw new UnknownAdviceTypeException(advisor.getAdvice()); } return interceptors.toArray(new MethodInterceptor[interceptors.size()]); }从这个方法可以看出,interceptors来源于advisor和this.adapters,从声明private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);可以看出,在方法调用的过程中并没有传递AdvisorAdapter过来,在这类中提供方法
public void registerAdvisorAdapter(AdvisorAdapter adapter) { this.adapters.add(adapter); }而这个方法被构造函数就有调用,外界也可能会调用,在spring aop(五)--ProxyFactory创建代理的实现,提到配置的Advisor链就是在initializeAdvisorChain()完成的,
Object advice; if (this.singleton || this.beanFactory.isSingleton(name)) { //从容器得到advice advice = this.beanFactory.getBean(name); } else { // It's a prototype Advice or Advisor: replace with a prototype. // Avoid unnecessary creation of prototype bean just for advisor chain initialization. advice = new PrototypePlaceholderAdvisor(name); } //添加advice addAdvisorOnChainCreation(advice, name);再看看addAdvisorOnChainCreation
private void addAdvisorOnChainCreation(Object next, String name) { //将advice转为Advisor Advisor advisor = namedBeanToAdvisor(next); if (logger.isTraceEnabled()) { logger.trace("Adding advisor with name '" + name + "'"); } //添加Advisor addAdvisor(advisor); } public void addAdvisor(Advisor advisor) { int pos = this.advisors.size(); addAdvisor(pos, advisor); }最终添加到org.springframework.aop.framework.AdvisedSupport#advisors
再回来,上面提及org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#DefaultAdvisorAdapterRegistry添加了MethodBeforeAdviceAdapter,AfterReturningAdviceAdapter,ThrowsAdviceAdapter到private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);
public interface AdvisorAdapter { //适配器是否能理解此advice对象 boolean supportsAdvice(Advice advice); //将advisor转为AOP Alliance MethodInterceptor,即对Advisor进行封装 MethodInterceptor getInterceptor(Advisor advisor); }以MethodBeforeAdviceAdapter为例
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable { @Override public boolean supportsAdvice(Advice advice) { return (advice instanceof MethodBeforeAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); return new MethodBeforeAdviceInterceptor(advice); } } public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable { private MethodBeforeAdvice advice; /** * Create a new MethodBeforeAdviceInterceptor for the given advice. * @param advice the MethodBeforeAdvice to wrap */ public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override public Object invoke(MethodInvocation mi) throws Throwable { this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() ); return mi.proceed(); } }从MethodBeforeAdviceInterceptor设计的invoke可以看出先触发了advice的before回调,然后再调用MethodInvocation的proceed.根据AOP的配置规则,ReflectiveMethodInvocation会触发拦截器的invoke方法,最终根据不同的advice类型,触发不同的advice的拦截器封装,比如这个org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor#invoke在调用方法前会先调用before方法,从而达到前置通知的效果.