Spring AOP

2020/11/27 posted in  Spring

AOP

AOP 原理

  1. @EnableAspectJAutoProxy
    1. @Import(AspectJAutoProxyRegistrar.class) 给容器导入AspectJAutoProxyRegistrar;

    2. 利用AspectJAutoProxyRegistrar 给容器中注册

      internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator

  2. AnnotationAwareAspectJAutoProxyCreator

AOP 流程

  1. 创建IOC容器

  2. 注册配置类,refresh() 刷新容器

  3. registerBeanPostProcessors() 注册拦截bean创建的bean后置处理器

    • 获取IOC容器中已经定义的需要创建的Bean后置处理器

    • 容器中添加别的后置处理器

    • 优先注册实现PriorityOrdered接口的后置处理器

    • 再注册实现Ordered接口的后置处理器

    • 注册没有实现优先级接口的后置处理器

    • 注册BeanPostProcessors,
      创建internalAutoProxyCreator的BeanPostProcessors[AnnotationAwareAspectJAutoProxyCreator ]

      1. 创建Bean的实例
      2. populateBean:给各种bean的属性赋值
      3. initializeBean:初始化Bean
        1. invokeAwareMethods: aware接口的方法处理
        2. applyBeanPostProcessorsBeforeInitialization:后置处理器的调用BeforeInitialization
        3. invokeInitMethods:自定义初始化方法
        4. applyBeanPostProcessorsAfterInitialization:后置处理器的调用AfterInitialization
      4. BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;----- aspectJAdvisorsBuilder
    • 把BeanPostProcessor注册到BeanFactory中; beanFactory.addBeanPostProcessor(postProcessor);

  4. finishBeanFactoryInitialization(beanFactory):创建剩余的单实例Bean

    1. 遍历获取容器中所有的Bean,依次创建对象getBean(beanName);

      getBean->doGetBean()->getSingleton()->

    2. 创建Bean:先从缓存中获取

    3. createBean:resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation

      后置处理器返回代理对象;

      【BeanPostProcessor是在Bean对象创建完成初始化前后调用的】 【InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象的】

    4. doCreateBean(beanName, mbdToUse, args):真正的去创建一个bean实例

      Object bean = null;
      // .....
      bean = applyBeanPostProcessorsBeforeInstantiation()
      // 拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor;
      // 就执行postProcessBeforeInstantiation
      if (bean != null) {
          bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
      } 
      
  5. AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】 的作用

    1. 每一个bean创建之前,调用postProcessBeforeInstantiation()

      1. 判断当前bean是否在advisedBeans中(保存了所有需要增强bean)

      2. 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)

      3. 是否需要跳过:永远返回false;

    2. 创建对象postProcessAfterInitialization:wrapIfNecessary(bean, beanName, cacheKey)

      1. 获取当前bean的所有增强器(通知方法)

      2. 保存当前bean在advisedBeans中

      3. 如果当前bean需要增强,创建当前bean的代理对象

      4. 给容器中返回当前组件使用cglib增强了的代理对象;

      5. 以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程

    3. 目标方法执行: 容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx)

      1. CglibAopProxy.intercept():拦截目标方法的执行
      2. 根据ProxyFactory对象获取将要执行的目标方法拦截器链
        1. 保存所有拦截器 1个默认的ExposeInvocationInterceptor 和 4个增强器;
        2. 遍历所有的增强器,将其转为Interceptor
      3. 如果没有拦截器链,直接执行目标方法
      4. 如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链等信息传入创建一个 CglibMethodInvocation 对象,并调用 proceed();
      5. 拦截器链的触发过程
        1. 如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法
        2. 链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
        3. 拦截器链的机制,保证通知方法与目标方法的执行顺序;