AOP的interceptors从哪里来的?

上次在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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_34116044

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值