spring中AutowiredAnnotationBeanPostProcessor的注册时机

Posted 渭城朝雨浥轻尘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring中AutowiredAnnotationBeanPostProcessor的注册时机相关的知识,希望对你有一定的参考价值。


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

xml方式

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

@Test
public void test() throws Exception
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-test.xml");

Student student = (Student)applicationContext.getBean("student");
System.out.println(student.getUsername()+" "+student.getPassword());


spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_02spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_03

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_04spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_05

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_06spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_07

 

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_08spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_09

创建 BeanFactory,然后 loadBeanDefinitionsspring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_10spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_11

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_12spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_13

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_14spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_15

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_16spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_17

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_18spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_19

 也是调do开头的方法进行真正的干活spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_20spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_21

 开始解析前面的Document了

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_22spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_23

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_24spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_25

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_26spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_27

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_28spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_29

 

那就继续解析吧

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_30spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_31

 调到NamespaceHandlerSupport的parse方法

spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_32spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_33

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_34spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_35

 

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_36spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_37

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


 

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

注解方式

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

@Test
public void test()
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("com.zubus.bean");
BeforeInstantiation bean = ac.getBean(BeforeInstantiation.class);
bean.doSomeThing();

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_38

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

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_39spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_40

 

里面会new一个AnnotatedBeanDefinitionReader

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_41spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_42

 spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_43spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_44

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

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_45

spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_46spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_47

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

 spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_48spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_49

没错,正是在下

spring中AutowiredAnnotationBeanPostProcessor的注册时机_spring_50spring中AutowiredAnnotationBeanPostProcessor的注册时机_springboot_51

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

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

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

请看下回分解~


以上是关于spring中AutowiredAnnotationBeanPostProcessor的注册时机的主要内容,如果未能解决你的问题,请参考以下文章

Spring Day01 Spring 框架概述以及Spring中基于XML的IOC配置

学习笔记——Spring简介;Spring搭建步骤;Spring的特性;Spring中getBean三种方式;Spring中的标签

spring中 实体类在啥时候交给spring容器管理?

怎么把自己创建的对象加到spring容器中。让spring管理

如何在Maven中配置Spring依赖

Spring中如何在非Spring管理的Bean中获取到Spring管理的Bean并操作