• Spring注解驱动之AnnotationAwareAspectJAutoProxyCreator详解(二)


    概述

    在上一讲中,我们通过简单的人工分析,为AnnotationAwareAspectJAutoProxyCreator这个类中有关后置处理器以及自动装配BeanFactoryAware接口的那些方法都打上了一些断点,而且还为MainConfigOfAOP配置类中的两个方法打上了断点。
    接下来,我们就以debug模式来运行IOCTest_AOP测试类,仔细分析一下整个流程。

    创建和注册AnnotationAwareAspectJAutoProxyCreator的过程

    以debug模式来运行IOCTest_AOP测试类之后,会先来到AbstractAdvisorAutoProxyCreator类的setBeanFactory()方法中,如下图所示。
    在这里插入图片描述
    可以看到这一步是传入主配置类来创建IOC容器,怎么创建的呢?我们点击方法调用栈中test01()方法上面的那个方法,就来到下面这个地方了。
    在这里插入图片描述
    可以看到,传入主配置类来创建IOC容器使用的是AnnotationConfigApplicationContext类的有参构造器,具体分为下面三步:

    1. 首先使用无参构造器创建对象。
    2. 再来把主配置类注册进来。
    3. 最后调用refresh()方法刷新容器,刷新容器就是要把容器中的所有bean都创建出来,也就是说这就像初始化容器一样。
      接下来,我们来看看容器刷新是怎么做的?
      在这里插入图片描述其中,该refresh()方法中有一行非常重要的代码,那就是:
    // Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);
    
    • 1
    • 2

    即注册bean的后置处理器。它的作用是用来方便拦截bean的创建。
    在这里插入图片描述
    现在来分析下到底是怎么注册bean的后置处理器的。

    1. 先安装类型拿到IOC容器中所有需要创建的后置处理器,即先获取IOC容器中已经定义了的需要创建对象的所有BeanPostProcessor。如下代码所示:
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    
    • 1

    那IOC容器中的已定义的BeanPostProcessor从哪里来呢?
    在创建IOC容器是,需要先传入配置类,而我们在解析配置类的时候,由于这个配置类里面有个@EnableAspectJAutoProxy注解,该注解会在容器中注册一个AnnotationAwareAspectJAutoProxyCreator(后置处理器),这仅仅是@EnableAspectJAutoProxy注解做的事,除此之外,容器中还有一些默认的后置处理器的定义。
    所以,程序运行到这,容器中已经有一些我们将要用的后置处理器定义了,只不过现在还没有创建这些后置处理器的bean实例。

    1. 继续往下看这个registerBeanPostProcessors()方法,可以看到它里面还有其他的逻辑,如下所示:
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    
    • 1

    这是给beanFactory中添加一些其他的BeanPostProcessor,也就是说给容器中加别的BeanPostProcessor。

    1. 定位到了DefaultSingletonBeanRegistry类的getSingleton()方法
      在这里插入图片描述
      也就是说如果从IOC容器中第一次获取单实例的bean出现问题,也即获取不到时,那么就会调用singletonFactory的getObject()方法。
      我们继续跟进方法调用栈,如下图所示,可以看到现在又定位到了AbstractBeanFactory抽象类的doGetBean()方法中。
      在这里插入图片描述
      可以发现,现在就是来创建bean了,也就是说如果获取不到就创建bean。实际上就是创建BeanPostProcessor对象,然后保存到容器中。
      接着再跟进方法调用栈,如下图所示,可以看到现在是定位到了AbstractAutowireCapableBeanFactory抽象类的doCreateBean()方法中。
      在这里插入图片描述
      程序停留在这儿,就是在初始化bean实例,说明bean实例已经创建好了,如果你要不信的话,那么可以往前翻阅该doCreateBean()方法,这时你应该会看到一个createBeanInstance()方法,说的就是bean实例的创建。创建的是哪个bean实例呢?就是名称为internalAutoProxyCreator的实例,该实例的类型就是我们之前经常说的AnnotationAwareAspectJAutoProxyCreator,即创建这个类型的实例。创建好了之后,就在程序停留的地方进行初始化。
      所以整个过程如下:
    • 首先创建bean实现。
    • 然后给bean的各种属性赋值。
    • 接着初始化bean(即调用initializeBean()方法),这个初始化bean其实特别的重要,因为我们这个后置处理器就是在bean初始化前后进行工作的。
      接下来,我们就来看看这个bean的实例是如何初始化的。继续跟进方法调用栈,如下图所示,可以看到现在是定位到了AbstractAutowireCapableBeanFactory抽象类的initializeBean()方法中。
      在这里插入图片描述

    初始化bean流程

    • 首先进入invokeAwareMethods方法,如下图。
      在这里插入图片描述
      其实,这个方法是来判断我们这个bean对象是不是Aware接口的,如果是,并且它还是BeanNameAware、BeanClassLoaderAware以及BeanFactoryAware这几个Aware接口中的其中一个,那么就调用相关的Aware接口方法,即处理Aware接口的方法回调。
      现在这个bean叫internalAutoProxyCreator,并且这个bean对象已经被创建了,创建出来的这个bean实现了BeanFactoryAware接口。
    • 还是回到AbstractAutowireCapableBeanFactory抽象类的initializeBean()方法中。如果invokeAwareMethods()这个方法执行完了以后,那么后续又会发生什么呢?
      往下翻阅initializeBean()方法,会发现有一个叫applyBeanPostProcessorsBeforeInitialization的方法,如下图所示。
      在这里插入图片描述
      这个方法调用完以后,会返回一个被包装的bean。

    该方法的意思其实就是应用后置处理器的postProcessBeforeInitialization()方法。我们可以进入该方法中去看一看,到底是怎么应用后置处理器的postProcessBeforeInitialization()方法的?
    在这里插入图片描述
    可以看到,它是拿到所有的后置处理器,然后再调用后置处理器的postProcessBeforeInitialization()方法,也就是说bean初始化之前后置处理器的调用在这儿。

    • 还是回到程序停留的地方,继续往下翻阅initializeBean()方法,你会发现还有一个叫invokeInitMethods的方法,即执行自定义的初始化方法。
      这个自定义的初始化方法呢,你可以用@bean注解来定义,指定一下初始化方法是什么,销毁方法又是什么,这个我们之前都说过了。
    • 自定义的初始化方法执行完以后,又有一个叫applyBeanPostProcessorsAfterInitialization的方法,该方法的意思其实就是应用后置处理器的postProcessAfterInitialization()方法。我们可以进入该方法中去看一看,到底是怎么应用后置处理器的postProcessAfterInitialization()方法的?
      在这里插入图片描述
      依旧是拿到所有的后置处理器,然后再调用后置处理器的postProcessAfterInitialization()方法。
      所以,后置处理器的这两个postProcessBeforeInitialization()与postProcessAfterInitialization()方法前后的执行,就是在这块体现。
      至此,整个这么一个流程下来以后,咱们的这个BeanPostProcessor,我们是以AnnotationAwareAspectJAutoProxyCreator(就是@EnableAspectJAutoProxy这个注解核心导入的BeanPostProcessor)为例来讲解的,就创建成功了。并且还调用了它的initBeanFactory()方法得到了一些什么aspectJAdvisorFactory和aspectJAdvisorsBuilder,这两个东东大家知道一下就行了。至此,整个initBeanFactory()方法我们就说完了,也就是说我们整个的后置处理器的注册以及创建过程就说完了。

    总结

    现在我们知道了registerBeanPostProcessors(beanFactory);其实就是拿到所有的BeanPostProcessor,然后调用beanFactory的addBeanPostProcessor方法将BeanPostProcessor注册到BeanFactory中。
    总之,就是把容器中所有的后置处理器全部创建bean实例,然后把这些bean实例初始化,最后添加到BeanFacotry中。

    参考

    Spring注解驱动开发第28讲——为你呕心沥血分析创建和注册AnnotationAwareAspectJAutoProxyCreator的过程,这应该是全网分析的最详细的了!

  • 相关阅读:
    Html -- 文字时钟
    高速花炮筒纸筒剪切机分切机设计(说明书+CAD图纸)
    一文详解窄脉冲LIV测试系统的特点和功能
    Linux系统双显示器4K分辨率配置
    VSCode配置 C/C++ 环境
    IDEA工具之debug第三方jar包源码顺序错乱
    ParallelGC 日志详解
    星戈瑞Cyanine5/CY5-NHS共价结合的选择性146368-14-1
    统计学的坑坑洼洼
    MySQL 允许SQL最大长度
  • 原文地址:https://blog.csdn.net/tianzhonghaoqing/article/details/126807150