• xml开发方式下AutowiredAnnotationBeanPostProcessor的注册时机


    AutowiredAnnotationBeanPostProcessor是实现@Autowired的关键,它本身是在何时添加到sping容器中的?

    xml方式

    在使用xml方式开发的过程中,我们程序入口一般是ClassPathXmlApplicationContext

    1. @Test
    2. public void test() throws Exception{
    3. ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-test.xml");
    4. Student student = (Student)applicationContext.getBean("student");
    5. System.out.println(student.getUsername()+" "+student.getPassword());
    6. }

    创建ClassPathXmlApplicationContext时,会调用this构造函数

     在构造函数中调用父类构造函数,完成一些属性的加载,以及配置文件路径的解析工作,然后进入正题——refresh()

     

    在核心的refresh()方法中,有一个步骤是创建BeanFactory

     

    创建BeanFactory后,它顺带把我们的xml配置文件也给解析了

    创建 BeanFactory,然后 loadBeanDefinitions

     

    loadBeanDefinitions的过程比较复杂,有兴趣的可以去逐行degbug源码,这里就贴几个关键步骤

     几个相同名称的loadBeanDefinitions调来调去,最好调到了真正干活的doLoadBeanDefinitions

     loadBeanDefinitions并不是这次关注的焦点,doLoadBeanDefinitions的细节也就不用深究了,重要的是在doLoadBeanDefinitions完成后,还只是得到了一个Document得对象,还不是我们要的bean定义信息,即BeanDefinition,所以继续进行了一个叫registerBeanDefinitions的步骤

     在这个registerBeanDefinitions的过程中,九曲十八弯

     也是调do开头的方法进行真正的干活

     开始解析前面的Document了

     解析的标签分两种类型,一种是DefaultElement,一种是CustomElement

     扯个题外话,什么是DefaultElement,这四个就是了,分别是import、alias、bean、beans,换句话说,除了这四个,其他的都是CustomElement

     在我的测试环境中,第一个标签是context,自然就是走parseCustomElement

     

    那就继续解析吧

     调到NamespaceHandlerSupport的parse方法

     再往下走的又是ComponentScanBeanDefinitionParser的parse方法,终于到头了,把标签解析并封装成了BeanDefinitionHolder,而后又有一个动作registerComponents

     

    就是这个不起眼的小动作,registerComponents,里面蕴含玄机

     在这里面执行了一个AnnotationConfigUtils.registerAnnotationConfigProcessors,就是在这里完成了AutowiredAnnotationBeanPostProcessor的注册

     

    总而言之,简而言之,就是在创建容器后,loadBeanDefinitions时注册的。

    注解方式

    同样整一个测试方法,即这次new的是AnnotationConfigApplicationContext 而不是上面的ClassPathXmlApplicationContext

    1. @Test
    2. public void test() {
    3. AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("com.zubus.bean");
    4. BeforeInstantiation bean = ac.getBean(BeforeInstantiation.class);
    5. bean.doSomeThing();
    6. }

    走的是不同的路线,进this()

     

    里面会new一个AnnotatedBeanDefinitionReader

     

     new AnnotatedBeanDefinitionReader()的过程中有个熟悉的身影

    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

    是不是和上面的xml解析后的registerComponents里的一模一样

     

    没错,正是在下

     

     至此,两种开发模式下的AutowiredAnnotationBeanPostProcessor注册时机我们已经掌握了

    这里仅仅是注册,后续就是再分析它是在哪没创建成对象的

    再后续就是分析它是在哪里被调用执行了

    请看下回分解~

  • 相关阅读:
    Python(10)函数
    MongoDB 索引和常用命令
    终于拿到了爆火全网的进一线大厂程序员必看的1700道java面试题
    create® 3入门教程-简单的动作
    python的类/方法引用---人机石头剪刀布游戏
    计算机毕业设计springboot驾校管理系统o2ehg源码+系统+程序+lw文档+部署
    ZooKeeper 之zkCli.sh 客户端一文读懂
    9.1、面向对象编程
    beanstalkd 启动跟停止【经常使用 nohup 和 & 配合来启动程序,如: nohup ./test &同时免疫SIGINT和SIGHUP信号】
    你听说过OTA吗?
  • 原文地址:https://blog.csdn.net/leisure_life/article/details/125570942