上次在AOP执行流程的分析中,我们研究了AOP底层实际是用了责任链模式执行了一堆的interceptors,如下图所示:
//调用运用了AOP的方法a.getB() System.out.println(a.getB());
这里我们看到当我们在getBean("a",A.class)的时候,看到a这个对象其实已经是一个cglib代理对象了,最关键的是,当我们点进去看这个a对象的时候,看到里面已经把给A这个类定义的一些advice放进去了。如下图所示:
而后来在执行的就是这些通知。所以这些advice到底是哪里来的,这就是今天要研究的东西。
首先有两个类可以作为我们研究的起点,一个是为A这个类创建对应的增强代理类的一个方法,就是AbstractAutoProxyCreator.createProxy(),另一个是CglibAopProxy.intercept()方法,也就是执行代理对象加强后的方法的方法。
这里我们用的还是之前的案例,有A和B这两个相互依赖的类,并且对A类使用的AOP
我们先找到了CglibAopProxy.getProxy()方法中有这样一句话:
//获取所有的callback函数,这些callback其实是一些拦截器,每个拦截器内部有包装了一堆的advice Callback[] callbacks = getCallbacks(rootClass);
在这个方法里其实主要就干了一件事:
//构建一个aopinterceptor,这个interceptor是为AOP调用的 Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised); //创建一堆的interceptor,为原先的bean加强用的interceptor Callback[] mainCallbacks = new Callback[] { aopInterceptor, // for normal advice targetInterceptor, // invoke target without considering advice, if optimized new SerializableNoOp(), // no override for methods mapped to this targetDispatcher, this.advisedDispatcher, new EqualsInterceptor(this.advised), new HashCodeInterceptor(this.advised) };
所以这里有一个很关键的问题,这个this.advised哪里来的?这里面包含了所有我们呢为这个当前这个类定义的一些advice,
1.this.advised哪里来的?
AbstractAutoProxyCreator.createProxy()方法中:
protected Object createProxy(Object... args){ //这些advices其实就是我们之前定义的一些advice Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); //....... return proxyFactory.getProxy(getProxyClassLoader()); }
AbstractAutoProxyCreator.wrapIfNecessary()方法中:
// Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(...)
AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()
//找到所有的预选advisors protected List<Advisor> findCandidateAdvisors() { // Add all the Spring advisors found according to superclass rules. List<Advisor> advisors = super.findCandidateAdvisors(); // Build Advisors for all AspectJ aspects in the bean factory. if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }
BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors()得到所有的advisors
在BeanFactoryAspectJAdvisorsBuilder这个类中维护了一个缓存用来存储所有的aspect和每个aspect里面的advices的entry键值对,这样子拿到的就是所谓的CandidateAdvisors(预选者),
2.怎么识别哪些advice是针对当前这个类定义的?
拿到CandidateAdvisors(预选者)之后,还要得到最后的eligibleAdvisors,还要过滤执行findAdvisorsThatCanApply方法,里面通过poingtcut表达式与类名进行了匹配
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new ArrayList<>(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor) { // already processed continue; } //匹配类名 if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }