spring源码深度解析---创建AOP代理之获取增强器

spring源码深度解析—创建AOP代理之获取增强器

在上一篇的博文中我们讲解了通过自定义配置完成了对AnnotationAwareAspectJAutoProxyCreator类型的自动注册,那么这个类到底做了什么工作来完成AOP的操作呢?首先我们看看AnnotationAwareAspectJAutoProxyCreator的层次结构,如下图所示:
这里写图片描述
从上图的类层次结构图中我们看到这个类实现了BeanPostProcessor接口,而实现BeanPostProcessor后,当Spring加载这个Bean时会在实例化前调用其postProcesssAfterIntialization方法,而我们对于AOP逻辑的分析也由此开始。
首先看下其父类AbstractAutoProxyCreator中的postProcessAfterInitialization方法:

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
        //根据给定的bean的class和name构建出个key,格式:beanClassName_beanName  
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            //如果它适合被代理,则需要封装指定bean  
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

在上面的代码中用到了方法wrapIfNecessary,继续跟踪到方法内部:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey)  
  {  
      //如果已经处理过  
     if(StringUtils.hasLength(beanName) && this.targetSourcedBeans.containsKey(beanName))  
          return bean;  
      //无需增强  
     if(Boolean.FALSE.equals(this.advisedBeans.get(cacheKey)))  
          return bean;  
      //给定的bean类是否代表一个基础设施类,基础设施类不应代理,或者配置了指定bean不需要自动代理  
     if(isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName))  
      {  
          this.advisedBeans.put(cacheKey, Boolean.FALSE);  
          return bean;  
      }  
      //如果存在增强方法则创建代理  
     Object specificInterceptors[] = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);  
      //如果获取到了增强则需要针对增强创建代理  
      if(specificInterceptors != DO_NOT_PROXY)  
      {  
          this.advisedBeans.put(cacheKey, Boolean.TRUE);  
          //创建代理  
          Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));  
          proxyTypes.put(cacheKey, proxy.getClass());  
          return proxy;  
      } else  
      {  
          this.advisedBeans.put(cacheKey, Boolean.FALSE);  
          return bean;  
      }  
  }  

函数中我们已经看到了代理创建的雏形。当然,真正开始之前还需要经过一些判断,比如是否已经处理过或者是否是需要跳过的bean,而真正创建代理的代码是从getAdvicesAndAdvisorsForBean开始的。
创建代理主要包含了两个步骤:
(1)获取增强方法或者增强器;
(2)根据获取的增强进行代理。
其中逻辑复杂,我们首先来看看获取增强方法的实现逻辑。是在AbstractAdvisorAutoProxyCreator中实现的,代码如下:

protected Object[] getAdvicesAndAdvisorsForBean(
        Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
   

    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

对于指定bean的增强方法的获取一定是包含两个步骤的,获取所有的增强以及寻找所有增强中使用于bean的增强并应用,那么findCandidateAdvisors与findAdvisorsThatCanApply便是做了这两件事情。当然,如果无法找到对应的增强器便返回DO_NOT_PROXY,其中DO_NOT_PROXY=null。

1. 获取增强器

由于我们分析的是使用注解进行的AOP,所以对于findCandidateAdvisors的实现其实是由AnnotationAwareAspectJAutoProxyCreator类完成的,我们继续跟踪AnnotationAwareAspectJAutoProxyCreator的findCandidateAdvisors方法。代码如下

protected List<Advisor> findCandidateAdvisors() {
    // Add all the Spring advisors found according to superclass rules.
    //当使用注解方式配置AOP的时候并不是丢弃了对XML配置的支持。  
    //在这里调用父类方法加载配置文件中的AOP声明  
    List<Advisor> advisors = super.findCandidateAdvisors();
    // Build Advisors for all AspectJ aspects in the bean factory.
    if (
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值