spring aop原理

195 阅读17分钟

aop:面向切面编程,把与核心业务逻辑无关的代码全部抽取出来,放置到某个地方集中管理,然后在具体运行时,再由容器动态织入这些共有代码

1 spring aop使用

注意:spring aop使用部分以普通的spring应用为例。(非springboot应用)

maven依赖

spring应用:

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.1.18.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.1.18.RELEASE</version>
</dependency>

springboot应用

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>2.2.11.RELEASE</version>
</dependency>

1.1 开启spring aop

1.1.1 spring应用开启aop(注解版)

使用ssm框架的项目就是spring应用(区别于springboot)

配置类上加@EnableAspectJAutoProxy注解开启aop

//开启spring aop
@EnableAspectJAutoProxy

@Configuration
public class AopConfiguration {
  
}

1.1.2 springboot应用开启sop

springboot应用默认就开启了aop。spring-boot-autoconfigure模块类路径下META-INF/spring.factories文件引入了AopAutoConfiguration自动配置类,AopAutoConfiguration类中使用了@EnableAspectJAutoProxy注解。

1.2 编写切面类

/**
 * 切面类
 */

@Aspect
public class LogAspects {

   /**
    * 抽取公共的切入点表达式
    *  1、本类引用
    *  2、其他类引用
    */
   @Pointcut("execution(public int com.dyzwj.aop.MathCalculator.div(..))")
   public void pointcut(){}

   @Before("pointcut()")
   public void logStart(JoinPoint joinPoint){
      Object[] args = joinPoint.getArgs();
      System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+ Arrays.asList(args)+"}");
   }

   //外类引用
   @After("com.dyzwj.aop.LogAspects.pointcut()")
   public void logEnd(JoinPoint joinPoint){
      System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
   }

   //JoinPoint一定要出现在参数表的第一位
   @AfterReturning(value = "pointcut()",returning = "result")
   public void logReturn(JoinPoint joinPoint, Object result){
      System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
   }

   @AfterThrowing(value = "pointcut()",throwing = "exception")
   public void logException(JoinPoint joinPoint,Exception exception){
      System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");

   }
}

1.3 业务逻辑代码(目标类)


//业务逻辑类 目标类
public class MathCalculator {

   public int div(int i,int j){
      System.out.println("MathCalculator...div...");
      return i/j;
   }
   
   //思考:结合切面类的切点表达式的配置,调用aa()方法会不会触发切面逻辑?不会
   public void aa(int i,int j){
//    System.out.println(this);
      this.div(i,j);
   }

}

1.4 配置

//显示开启spring aop
@EnableAspectJAutoProxy
@Configuration
public class AopConfiguration {

   //业务逻辑类加入到容器中
   @Bean
   public MathCalculator mathCalculator(){
      return new MathCalculator();
   }

   //切面类加入到容器中
   @Bean
   public LogAspects logAspects(){
      return new LogAspects();
   }

   @Bean
   public AA aa(){
      return new AA();
   }
}

1.5执行目标方法

public class AopMain {

   public static void main(String[] args) {
      //手动创建注解版的容器
      AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AopConfiguration.class);
      MathCalculator bean = annotationConfigApplicationContext.getBean(MathCalculator.class);
//    System.out.println(bean);
//    System.out.println(AopUtils.isAopProxy(bean));

      //bean.aa(10,2);
      //System.out.println();
      bean.div(10,2);
//    AA bean = annotationConfigApplicationContext.getBean(AA.class);
//    bean.bb(10,2);
   }
}

2 spring aop原理

源码版本说明

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.18.RELEASE</version>
</dependency>

spring支持的代理方式:

  • jdk动态代理

  • cglib代理

2.1 @EnableAspectJAutoProxy注解

//类上使用@Import注解导入了AspectJAutoProxyRegistrar,该类实现了ImportBeanDefinitionRegistrar接口,重写了registerBeanDefinitions()方法 
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

   boolean proxyTargetClass() default false;
   boolean exposeProxy() default false;
}

AspectJAutoProxyRegistrar

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

   /**
    * Register, escalate, and configure the AspectJ auto proxy creator based on the value
    * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
    * {@code @Configuration} class.
    */
   @Override
   public void registerBeanDefinitions(
         AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
      //注册beanDefinition == AnnotationAwareAspectJAutoProxyCreator
      AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

      AnnotationAttributes enableAspectJAutoProxy =
            AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
      if (enableAspectJAutoProxy != null) {
         if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
         }
         if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
            AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
         }
      }
   }

}

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary

public abstract class AopConfigUtils {

   /**
    * The bean name of the internally managed auto-proxy creator.
    */
   public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
         "org.springframework.aop.config.internalAutoProxyCreator";
         
 
    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
       return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
    }

    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
          BeanDefinitionRegistry registry, @Nullable Object source) {

       return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }


    private static BeanDefinition registerOrEscalateApcAsRequired(
          Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

       Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
       //如果当前注册器包含internalAutoProxyCreator
       if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
          BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
          if (!cls.getName().equals(apcDefinition.getBeanClassName())) {//如果当前类不是internalAutoProxyCreator
             int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
             int requiredPriority = findPriorityForClass(cls);
             if (currentPriority < requiredPriority) {//如果下标大于已存在的内部自动代理构造器,index越小,优先级越高
                apcDefinition.setBeanClassName(cls.getName());
             }
          }
          return null;
       }
       //如果当前注册器不包含internalAutoProxyCreator,则把当前类作为根定义
       RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
       beanDefinition.setSource(source);
       beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
       beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
       registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
       return beanDefinition;
    }


         
}

AspectJAutoProxyRegistrar#registerBeanDefinitions给容器中注册了bean id为internalAutoProxyCreator ==> AnnotationAwareAspectJAutoProxyCreator类型的bean

2.2 AnnotationAwareAspectJAutoProxyCreator

/**
 *
 *概述
 * 1、获取当前应用上下文中所有使用@AspectJ注解的切面类中的advice方法和所有Spring Advisor bean;
 * 获取所有advice方法/advisor的任务在AnnotationAwareAspectJAutoProxyCreator应用到每个bean创建时执行,但内部使用了缓存机制,所以真正的查找过程只发生在第一次被调用时。
 *
 * 2、在每个bean创建时检测该bean是否符合创建代理的条件,如果符合,则获取可以应用在该bean上的所有advise,为当前bean生成一个代理对象。
 * 是否符合条件的主要判断逻辑为AopUtils#findAdvisorsThatCanApply

 */
@SuppressWarnings("serial")
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

   @Nullable
   private List<Pattern> includePatterns;

   @Nullable
   private AspectJAdvisorFactory aspectJAdvisorFactory;

   @Nullable
   private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;


   @Override
   protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      // 使用基类方法初始化 beanFactory,真正的逻辑时构造一个能够从容器中获取所有
      super.initBeanFactory(beanFactory);

      // 下面的逻辑是构造 aspectJAdvisorsBuilder , 用于通过反射方法从容器中获取
      // 所有带有@AspectJ注解的 beans
      if (this.aspectJAdvisorFactory == null) {
         this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
      }

      this.aspectJAdvisorsBuilder =
            new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
   }


   // 找到容器中所有的Spring Advisor beans 和 @AspectJ 注解的 beans,都封装成
   // Advisor 形式返回一个列表
   @Override
   protected List<Advisor> findCandidateAdvisors() {
      // Add all the Spring advisors found according to superclass rules.
      /**
       *    使用基类Spring Advisor查找机制查找容器中所有的Spring Advisor
       *      其实就是父类使用所构造的BeanFactoryAdvisorRetrievalHelper从
       *      容器中获取所有的Spring Advisor beans。
       */
      List<Advisor> advisors = super.findCandidateAdvisors();
      // Build Advisors for all AspectJ aspects in the bean factory.
      if (this.aspectJAdvisorsBuilder != null) {
         /**
          * 使用aspectJAdvisorsBuilder从容器中获取所有@AspectJ 注解的bean,并将它们包装成Advisor
          */
         advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
      }
      // 现在列表advisors包含容器中所有的Spring Advisor beans 和 @AspectJ 注解的 beans,
      // 现在它们都以 Advisor 的形式存在
      return advisors;
   }

   // 判断指定的类是否是一个基础设置类:
   // 1. 如果父类的 isInfrastructureClass 断定它是一个基础设施类,就认为它是;
   // 2. 如果这是一个@Aspect注解的类,也认为这是一个基础设施类;
   // 一旦某个bean类被认为是基础设施类,那么将不会对该类实施代理机制

   @Override
   protected boolean isInfrastructureClass(Class<?> beanClass) {
      return (super.isInfrastructureClass(beanClass) ||
            (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
   }
}

看下AnnotationAwareAspectJAutoProxyCreator的继承结构

image.png

AnnotationAwareAspectJAutoProxyCreator extends 
		AspectJAwareAdvisorAutoProxyCreator extends 
			AbstractAdvisorAutoProxyCreator extends 
				AbstractAdvisorAutoProxyCreator extends 
					AbstractAutoProxyCreator extends ProxyProcessorSupport  implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

从AnnotationAwareAspectJAutoProxyCreator的继承结构看,主要关注后置处理器(SmartInstantiationAwareBeanPostProcessor:bean初始化前后)和自动装配BeanFactory的逻辑。

2.3 自动装配BeanFactory

AbstractAutoProxyCreator.setBeanFactory():实现BeanFactoryAware接口的setBeanFactory方法

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
      implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    
    private BeanFactory beanFactory;

    public void setBeanFactory(BeanFactory beanFactory) {
       this.beanFactory = beanFactory;
    }
}

AbstractAdvisorAutoProxyCreator.setBeanFactory():重写 -> super.setBeanFactory(); -> initBeanFactory(beanFactory);

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {

    private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;


    // 覆盖基类的setBeanFactory方法
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
       // 首先调用基类的setBeanFactory方法
       super.setBeanFactory(beanFactory);
       // 要求所设置的 beanFactory 也就是Spring bean容器必须使用类型 ConfigurableListableBeanFactory,
       // 否则抛出异常,声明当前 AdvisorAutoProxyCreator 只针对类型为 ConfigurableListableBeanFactory
       // 的容器工作

       if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
          throw new IllegalArgumentException(
                "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
       }
       // 上面设置完beanFactory检查过类型之后,立即初始化 beanFactory

       initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
    }
    // 初始化 beanFactory,初始化逻辑 :
    // 准备一个针对该beanFactory的BeanFactoryAdvisorRetrievalHelperAdapter赋值给this.advisorRetrievalHelper, 用于从beanFactory获取Spring Advisor(即通知)

    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       // 初始化从容器中获取符合条件的 Spring Advisor
       this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
    }
}

AnnotationAwareAspectJAutoProxyCreator.initBeanFactory():重写

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
   
    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       // 使用基类方法初始化 beanFactory,真正的逻辑时构造一个能够从容器中获取所有
       super.initBeanFactory(beanFactory);

       // 下面的逻辑是构造 aspectJAdvisorsBuilder , 用于通过反射方法从容器中获取
       // 所有带有@AspectJ注解的 beans
       if (this.aspectJAdvisorFactory == null) {
          this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
       }

       this.aspectJAdvisorsBuilder =
             new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
    }
}

自动装配BeanFactory主要做了两件事:

  • 初始化BeanFactoryAdvisorRetrievalHelperAdapter:从beanFactory获取Spring Advisor(即通知)

  • 初始化BeanFactoryAspectJAdvisorsBuilderAdapter:通过反射从容器中获取所有带有@AspectJ注解的 bean

2.4 spring bean的生命周期

(1)创建(包括属性赋值):
    - 单实例 容器启动的时候创建对象
    - 多实例 每次获取的时候创建对象

(2)BeanPostProcessor.postProcessBeforeInitialization

(3)初始化:对象创建完成,并赋好值,调用初始化方法

(4)BeanPostProcessor.postProcessAfterInitialization

(5)销毁:
    - 单实例 容器关闭的时候
    - 多实例 容器不会管理多实例bean,不会调用销毁方法
何为初始化?
spring支持的bean的初始化方式:
(1) @Bean(initMethod,destroyMethod);
(2) 通过让bean实现InitializingBean定义初始化逻辑,实现DisposableBean定义销毁逻辑(代码有侵入)
注:Spring不推荐使用InitializationBean 来调用其初始化方法,因为它不必要地将代码耦合到Spring
(3) 使用JSR250规范提供的注解:spring中提供了CommonAnnotationBeanPostProcessor负责支持@PostConstruct@PreDestroy
    - @PostConstruct:在bean创建并完成属性赋值后,执行初始化逻辑
    - @PreDestroy:在容器销毁bean之前执行销毁逻辑

既然支持多种初始化方式,那么这几种初始化方式的顺序是什么样的?

  • @PostConstruct

  • InitializingBean

  • @Bean(initMethod)

2.5 后置处理器逻辑

其实spring的BeanPostProcessor贯穿spring bean的生命周期(BeanPostProcessor还有许多子接口)。主要作用有:

  • 推断构造方法
  • 为循环依赖做准备
  • 属性注入
  • aop

现在来看@EnableAspectJAutoProxy给容器中导入的bean-AnnotationAwareAspectJAutoProxyCreator

image.png

看框中的部分,其父类AbstractAutoProxyCreator实现了BeanPostProcessor接口的postProcessAfterInitialization方法,在该方法中,会判断是否需要对bean进行包装(即代理)。

AbstractAutoProxyCreator#wrapIfNecessary源码阅读建议:先把代理的整体的流程弄清楚,再去查看子类实现的细节,比如getAdvicesAndAdvisorsForBean方法,最后自己跟着源码走一遍

2.5.1 是否需要进行代理

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
      implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
 
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
       if (bean != null) {
          Object cacheKey = getCacheKey(bean.getClass(), beanName);

          if (this.earlyProxyReferences.remove(cacheKey) != bean) {
             /**
              * earlyProxyReferences.remove(cacheKey) != bean为true 表示bean还没有进行aop
              * 在处理循环依赖时,有些bean提前完成了aop,会放到earlyProxyReferences集合中,因为已经进行了aop,所以此时就不需要进行aop了
              * 一般的bean在执行到此处时,不会再earlyProxyReferences结合中 所以都会进入此分支
              */
             return wrapIfNecessary(bean, beanName, cacheKey);
          }
       }
       return bean;
    }
   
   
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
       ///如果是用户自定义获取实例,不需要增强处理,直接返回
       if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
          return bean;
       }
       // 查询map缓存,标记过false,不需要增强直接返回
       if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
          return bean;
       }
       // 判断一遍springAOP基础构建类或需要跳过的,标记为false,不需要增强直接返回
       if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
          this.advisedBeans.put(cacheKey, Boolean.FALSE);
          return bean;
       }

       /**
        * // 获取针对该bean的所有专用拦截器对象,对返回值数组需要分三种情况考虑 :
        *        // 1. 返回数组有值 :  需要做代理,使用专用拦截器和通用拦截器
        *        // 2. 返回数组无值,为空 : 需要做代理,仅使用通用拦截器
        *        // 3. 返回为null : 不要给当前 bean 做代理
        *        //  当前类 getAdvicesAndAdvisorsForBean 方法其实是一个抽象方法,具体实现由实现子类提供
        */
       //获取当前bean的所有候选增强器(即当前bean符合切点表达式的)
       //AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
       Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
       //如果存在增强器
       if (specificInterceptors != DO_NOT_PROXY) {
          //把当前bean保存在增强过的bean集合advisedBeans中  // 标记增强为TRUE,表示需要增强实现
          this.advisedBeans.put(cacheKey, Boolean.TRUE);
          //创建当前bean的代理对象 生成增强代理类
          Object proxy = createProxy(
                bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
          //保存在proxyType中
          this.proxyTypes.put(cacheKey, proxy.getClass());
          //给容器中返回当前组件使用cglib增强了的代理对象
          //以后从容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程
          return proxy;
       }
       // 如果不存在增强,标记false,作为缓存,再次进入提高效率
       this.advisedBeans.put(cacheKey, Boolean.FALSE);
       return bean;
    }
    
  
    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
          @Nullable Object[] specificInterceptors, TargetSource targetSource) {
       // 如果是ConfigurableListableBeanFactory接口(咱们DefaultListableBeanFactory就是该接口的实现类)则,暴露目标类
       if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
          //给beanFactory->beanDefinition定义一个属性:k=AutoProxyUtils.originalTargetClass,v=需要被代理的bean class
          AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
       }

       ProxyFactory proxyFactory = new ProxyFactory();
       //复制配置信息
       proxyFactory.copyFrom(this);
       //如果不是代理目标类
       if (!proxyFactory.isProxyTargetClass()) {//如果beanFactory定义了代理目标类(CGLIB)
          if (shouldProxyTargetClass(beanClass, beanName)) {//代理工厂设置代理目标类
             proxyFactory.setProxyTargetClass(true);
          }
          else {//否则设置代理接口(JDK)
             evaluateProxyInterfaces(beanClass, proxyFactory);
          }
       }

       // 将针对当前 bean 的所有的专用拦截器和容器中的通用拦截器一并包装成 Spring Advisor 对象
       // 用于创建最终的代理对象
       // 构建最终适用于该bean的所有Advisor拦截器:
       // 1. 从容器获取通用拦截器
       // 2. 加上仅仅适用于该bean的专用拦截器 : specificInterceptors
       Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
       //将advisors保存到proxyFactory中
       proxyFactory.addAdvisors(advisors);
       proxyFactory.setTargetSource(targetSource);
       // 定制化 proxyFactory, 方法#customizeProxyFactory在本类是一个空方法,
       // 这里主要是留给实现子类一个定制 proxyFactory 的机会
       customizeProxyFactory(proxyFactory);//空方法,留给子类拓展用
       //用于控制代理工厂是否还允许再次添加通知,默认为false(表示不允许)
       proxyFactory.setFrozen(this.freezeProxy);
       if (advisorsPreFiltered()) {//默认false,上面已经前置过滤了匹配的增强Advisor
          proxyFactory.setPreFiltered(true);
       }
       //创建代理对象,spring自动决定
      
       //ProxyFactory.getProxy()
       return proxyFactory.getProxy(getProxyClassLoader());
    }
    
    
    //AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass重写了该方法
    protected boolean isInfrastructureClass(Class<?> beanClass) {
       boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
             Pointcut.class.isAssignableFrom(beanClass) ||
             Advisor.class.isAssignableFrom(beanClass) ||
             AopInfrastructureBean.class.isAssignableFrom(beanClass);
       if (retVal && logger.isTraceEnabled()) {
          logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
       }
       return retVal;
    }

    //AspectJAwareAdvisorAutoProxyCreator#shouldSkip重写了该方法
    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
       return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
    }
}

2.5.2 代理逻辑

AbstractAdvisorAutoProxyCreator


/**
 * AbstractAdvisorAutoProxyCreator自身实现了基类定义的抽象方法#getAdvicesAndAdvisorsForBean()用于从容器中获取针对某个bean可用的AOP Advice和Spring Advisor bean。
 * 并且AbstractAdvisorAutoProxyCreator对#getAdvicesAndAdvisorsForBean()的实现只使用容器中的Spring Advisor,而不考虑AOP Advice。

 AbstractAdvisorAutoProxyCreator约定一个bean需要被自动代理的条件是:容器中存在至少一个跟该bean匹配的Spring Advisors。这里一个bean跟容器中某个Spring Advisor bean是否匹配的匹配逻辑如下 :
 1、AbstractAdvisorAutoProxyCreator自身提供一个方法boolean isEligibleAdvisorBean(String beanName)来根据Advisor bean名称声明该Advisor是否符合条件(此方法的缺省实现为总是返回true,子类可以覆盖实现该方法),当前APC工作时会首先从容其中筛选出所有符合该条件的Spring Advisors作为候选;
 2、从上面的Spring Advisors候选中,利用bean类/方法上的注解信息再次筛选,选出那些跟当前bean匹配的Spring Advisors作为最终要包裹到当前bean的Spring Advisors。

 有顺序要求的Spring Advisor可以实现接口org.springframework.core.Ordered接口,因为AbstractAdvisorAutoProxyCreator会对符合条件的Spring Advisor做相应的排序然后才包裹到目标bean上。
 */
@SuppressWarnings("serial")
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {

   @Nullable
   private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;


   // 覆盖基类的setBeanFactory方法
   @Override
   public void setBeanFactory(BeanFactory beanFactory) {
      // 首先调用基类的setBeanFactory方法
      super.setBeanFactory(beanFactory);
      // 要求所设置的 beanFactory 也就是Spring bean容器必须使用类型 ConfigurableListableBeanFactory,
      // 否则抛出异常,声明当前 AdvisorAutoProxyCreator 只针对类型为 ConfigurableListableBeanFactory
      // 的容器工作

      if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
         throw new IllegalArgumentException(
               "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
      }
      // 上面设置完beanFactory检查过类型之后,立即初始化 beanFactory
      initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
   }

   protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      /**
       *     // 准备一个针对该beanFactory的BeanFactoryAdvisorRetrievalHelperAdapter赋值给this.advisorRetrievalHelper,
       *     用于从beanFactory获取Spring Advisor(即通知)。
       */
      // 初始化从容器中获取符合条件的 Spring Advisor
      this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
   }



   // 找到针对某个bean的所有符合条件的Advisor/Advice,如果结果为null,将不会为该bean创建代理
   @Override
   @Nullable
   protected Object[] getAdvicesAndAdvisorsForBean(
         Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
      // 获取容器中所有针对 beanClass,beanName 可用的 Spring Advisors
      //找到合格的增强器(适用于当前bean的 即当前bean符合切点表达式的)
      List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
      if (advisors.isEmpty()) {
         // 如果一个可用的 Spring Advisor 都没有找到则返回 null,表示不要给当前bean创建代理
         // DO_NOT_PROXY 其实是一个为 null 的常量,用于表示:
         // 如果找不到符合条件的Advisor,就不要为该bean创建代理
         return DO_NOT_PROXY;
      }
      return advisors.toArray();
   }


   protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
      //找到所有候选的增强器
      // 从容器中找到所有的 Spring Advisors bean 组件作为候选,此结果尚未针对当前 bean 进行筛选
      // 当前类中方法 #findCandidateAdvisors() 是一个抽象方法,要求由子类提供实现
      List<Advisor> candidateAdvisors = findCandidateAdvisors();
      // 将每个候选 Spring Advisor 针对当前 bean 进行筛选,留下符合条件的
      //从中找到能适用在当前bean的增强器
      List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
      // 对符合条件的 Spring Advisors 列表做扩展,当前类的该实现方法为空实现,
      // 子实现类可以重写该方法做相应的扩展
      extendAdvisors(eligibleAdvisors);
      if (!eligibleAdvisors.isEmpty()) {
         //给增强器排序
         eligibleAdvisors = sortAdvisors(eligibleAdvisors);
      }
      return eligibleAdvisors;
   }

   protected List<Advisor> findCandidateAdvisors() {
      Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
      //在容器中找advisor
      return this.advisorRetrievalHelper.findAdvisorBeans();
   }

 
   protected List<Advisor> findAdvisorsThatCanApply(
         List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
      // ProxyCreationContext 使用了一个 ThreadLocal 变量保持当前正在进行代理创建的bean,
      // 在代理创建过程中,比如对pointcut表达式求值时会使用到 ProxyCreationContext,
      // 由此可见,某个bean的代理创建必须在同一个线程内完成,不能跨线程

      ProxyCreationContext.setCurrentProxiedBeanName(beanName);
      try {

         //找可以使用的增强器
         // 具体检查每个advisor是否需要应用到该bean的逻辑委托给AopUtils完成,这里不做深入分析,
         return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
      }
      finally {
         // 已经完成advisor和bean的匹配过程,清除ProxyCreationContext
         ProxyCreationContext.setCurrentProxiedBeanName(null);
      }
   }

   /**
    * Return whether the Advisor bean with the given name is eligible
    * for proxying in the first place.
    * @param beanName the name of the Advisor bean
    * @return whether the bean is eligible
    */
   protected boolean isEligibleAdvisorBean(String beanName) {
      return true;
   }
}

ProxyFactory

public class ProxyFactory extends ProxyCreatorSupport {
    
    public Object getProxy(@Nullable ClassLoader classLoader) {
       //JdkDynamicAopProxy:jdk动态代理   -> 实现了接口
       //ObjenesisCglibAopProxy:cglib动态代理  -> 未实现接口
       return createAopProxy().getProxy(classLoader);
    }
}

AdvisedSupport

public class ProxyCreatorSupport extends AdvisedSupport {

    protected final synchronized AopProxy createAopProxy() {
       if (!this.active) {
          activate();
       }
       //决定使用jdk动态代理还是cglib代理
       //DefaultAopProxyFactory#createAopProxy
       return getAopProxyFactory().createAopProxy(this);
    }
}

2.5.3 采用哪种代理方式

DefaultAopProxyFactory:aop代理工厂,决定目标对象采用jdk动态代理或cglib代理

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

   @Override
   public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
      if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
         Class<?> targetClass = config.getTargetClass();
         if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class: " +
                  "Either an interface or a target is required for proxy creation.");
         }
         //jdk动态代理
         if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
         }
         return new ObjenesisCglibAopProxy(config);
      }
      else {
         return new JdkDynamicAopProxy(config);
      }
   }
}

CglibAopProxy:cglib创建代理

class CglibAopProxy implements AopProxy, Serializable {
   
    public Object getProxy(@Nullable ClassLoader classLoader) {
       if (logger.isTraceEnabled()) {
          logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
       }

       try {
          Class<?> rootClass = this.advised.getTargetClass();
          Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

          Class<?> proxySuperClass = rootClass;
          if (ClassUtils.isCglibProxyClass(rootClass)) {
             proxySuperClass = rootClass.getSuperclass();
             Class<?>[] additionalInterfaces = rootClass.getInterfaces();
             for (Class<?> additionalInterface : additionalInterfaces) {
                this.advised.addInterface(additionalInterface);
             }
          }

          // Validate the class, writing log messages as necessary.
          validateClassIfNecessary(proxySuperClass, classLoader);

          // Configure CGLIB Enhancer...
          Enhancer enhancer = createEnhancer();
          if (classLoader != null) {
             enhancer.setClassLoader(classLoader);
             if (classLoader instanceof SmartClassLoader &&
                   ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                enhancer.setUseCache(false);
             }
          }
          enhancer.setSuperclass(proxySuperClass);
          enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
          enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
          enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

          //获取回调列表 (拦截器链)
          Callback[] callbacks = getCallbacks(rootClass);
          Class<?>[] types = new Class<?>[callbacks.length];
          for (int x = 0; x < types.length; x++) {
             types[x] = callbacks[x].getClass();
          }
          // fixedInterceptorMap only populated at this point, after getCallbacks call above
          enhancer.setCallbackFilter(new ProxyCallbackFilter(
                this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
          enhancer.setCallbackTypes(types);

          // Generate the proxy class and create a proxy instance.
          //生成代理类以及创建代理
          return createProxyClassAndInstance(enhancer, callbacks);
       }
       catch (CodeGenerationException | IllegalArgumentException ex) {
          throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
                ": Common causes of this problem include using a final class or a non-visible class",
                ex);
       }
       catch (Throwable ex) {
          // TargetSource.getTarget() failed
          throw new AopConfigException("Unexpected AOP exception", ex);
       }
    }
    
    
   
    private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
       // Parameters used for optimization choices...
       // 对 expose-proxy 属性的处理
       boolean exposeProxy = this.advised.isExposeProxy();
       boolean isFrozen = this.advised.isFrozen();
       boolean isStatic = this.advised.getTargetSource().isStatic();

       // Choose an "aop" interceptor (used for AOP calls).
       /**
        * 将拦截器封装在 DynamicAdvisedInterceptor 中
        *
        *  链式调用
        */
       Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

       // Choose a "straight to target" interceptor. (used for calls that are
       // unadvised but can return this). May be required to expose the proxy.
       Callback targetInterceptor;
       if (exposeProxy) {
          targetInterceptor = (isStatic ?
                new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
                new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
       }
       else {
          targetInterceptor = (isStatic ?
                new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
                new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
       }

       // Choose a "direct to target" dispatcher (used for
       // unadvised calls to static targets that cannot return this).
       Callback targetDispatcher = (isStatic ?
             new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

       //主回调
       Callback[] mainCallbacks = new Callback[] {
             // 将拦截器链加入 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)
       };

       Callback[] callbacks;

       // If the target is a static one and the advice chain is frozen,
       // then we can make some optimizations by sending the AOP calls
       // direct to the target using the fixed chain for that method.
       if (isStatic && isFrozen) {
          Method[] methods = rootClass.getMethods();
          Callback[] fixedCallbacks = new Callback[methods.length];
          this.fixedInterceptorMap = new HashMap<>(methods.length);

          // TODO: small memory optimization here (can skip creation for methods with no advice)

          /**
           * 遍历类中的所有方法
           */
          for (int x = 0; x < methods.length; x++) {
             Method method = methods[x];
             /**
              * 获取每个方法对应的拦截器链
              */
             List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
             fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
                   chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
             this.fixedInterceptorMap.put(methods.toString(), x);
          }

          // Now copy both the callbacks from mainCallbacks
          // and fixedCallbacks into the callbacks array.

          /**
           * 根据主回调和
           */
          callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
          System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
          System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
          this.fixedInterceptorOffset = mainCallbacks.length;
       }
       else {
          callbacks = mainCallbacks;
       }
       return callbacks;
    }

    
    //cglib创建代理对象的方式,感兴趣的可以研究一下
    protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
       enhancer.setInterceptDuringConstruction(false);
       enhancer.setCallbacks(callbacks);
       return (this.constructorArgs != null && this.constructorArgTypes != null ?
             enhancer.create(this.constructorArgTypes, this.constructorArgs) :
             enhancer.create());
    }
    
    

}

JdkDynamicAopProxy:jdk动态代理

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {


    public Object getProxy(@Nullable ClassLoader classLoader) {
       if (logger.isTraceEnabled()) {
          logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
       }
       Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
       findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
       /**
        * this(JdkDynamicAopProxy)就是一个InvocationHandler对象 目标对象执行时,会调用到InvocationHandler.invoke()方法
        */
       return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }
    

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       Object oldProxy = null;
       boolean setProxyContext = false;

       TargetSource targetSource = this.advised.targetSource;
       Object target = null;

       try {
          if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
             // The target does not implement the equals(Object) method itself.
             return equals(args[0]);
          }
          else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
             // The target does not implement the hashCode() method itself.
             return hashCode();
          }
          else if (method.getDeclaringClass() == DecoratingProxy.class) {
             // There is only getDecoratedClass() declared -> dispatch to proxy config.
             return AopProxyUtils.ultimateTargetClass(this.advised);
          }
          else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                method.getDeclaringClass().isAssignableFrom(Advised.class)) {
             // Service invocations on ProxyConfig with the proxy config...
             return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
          }

          Object retVal;

          if (this.advised.exposeProxy) {
             // Make invocation available if necessary.
             oldProxy = AopContext.setCurrentProxy(proxy);
             setProxyContext = true;
          }

          // Get as late as possible to minimize the time we "own" the target,
          // in case it comes from a pool.
          target = targetSource.getTarget();
          Class<?> targetClass = (target != null ? target.getClass() : null);

          // Get the interception chain for this method.
          /**
           * 获取拦截器链
           */
          List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

          // Check whether we have any advice. If we don't, we can fallback on direct
          // reflective invocation of the target, and avoid creating a MethodInvocation.
          if (chain.isEmpty()) {
             // We can skip creating a MethodInvocation: just invoke the target directly
             // Note that the final invoker must be an InvokerInterceptor so we know it does
             // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
             /**
              * 如果拦截器链为空 直接执行目标方法
              */
             Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
             retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
          }
          else {
             /**
              * 如果有拦截器链,把需要执行的目标对象、目标方法、拦截器链等信息创建一个CglibMethodInvocation,
              * 并调用proceed()方法触发拦截器链和目标方法调用
              */
             // We need to create a method invocation...
             MethodInvocation invocation =
                   new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
             // Proceed to the joinpoint through the interceptor chain.
             retVal = invocation.proceed();
          }

          // Massage return value if necessary.
          Class<?> returnType = method.getReturnType();
          if (retVal != null && retVal == target &&
                returnType != Object.class && returnType.isInstance(proxy) &&
                !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
             // Special case: it returned "this" and the return type of the method
             // is type-compatible. Note that we can't help if the target sets
             // a reference to itself in another returned object.
             retVal = proxy;
          }
          else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
             throw new AopInvocationException(
                   "Null return value from advice does not match primitive return type for: " + method);
          }
          return retVal;
       }
       finally {
          if (target != null && !targetSource.isStatic()) {
             // Must have come from TargetSource.
             targetSource.releaseTarget(target);
          }
          if (setProxyContext) {
             // Restore old proxy.
             AopContext.setCurrentProxy(oldProxy);
          }
       }
    }
}

可以看到,无论是cglib代理还是jdk动态代理,都是将代理逻辑封装成拦截器链(责任链模式),而且拦截器链中的第一个拦截器是DynamicAdvisedInterceptor,因此,目标方法执行时,实际上会执行到拦截器链的中拦截器MethodInterceptor.invoke方法,即DynamicAdvisedInterceptor.invoke方法,再由DynamicAdvisedInterceptor向下进行传播。