0
点赞
收藏
分享

微信扫一扫

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机


 注解方式

写一个测试方法,new的是AnnotationConfigApplicationContext ,指定basePackages

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

进this()

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_前端

里面会new一个AnnotatedBeanDefinitionReader

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_构造函数_02

 

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_前端_03

 new AnnotatedBeanDefinitionReader()的过程中,有一行与众不同的代码

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_前端_04

继续跟进

 

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_前端_05

正是在这个方法内,把AutowiredAnnotationBeanPostProcessor的注册到了Set<BeanDefinitionHolder>中

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_java_06

 

 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());


}

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_java_07

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_java_08

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_构造函数_09

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_xml_10

创建 BeanFactory,然后 loadBeanDefinitions

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_构造函数_11

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_xml_12

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_构造函数_13

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_xml_14

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_前端_15

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_构造函数_16

 开始解析前面的Document了

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_xml_17

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_xml_18

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_java_19

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_xml_20

那就继续解析吧

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_数据库_21

 调到NamespaceHandlerSupport的parse方法

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_数据库_22

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_java_23

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

注解开发方式下AutowiredAnnotationBeanPostProcessor的注册时机_数据库_24

 在这里面的这个AnnotationConfigUtils.registerAnnotationConfigProcessors,是不是很熟悉没错,又是在下,就是这里完成了AutowiredAnnotationBeanPostProcessor的注册

比注解方式复杂太多,隐藏的太深了,总而言之,简而言之,xml方式就是在创建容器后,loadBeanDefinitions时注册的。

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

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

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

请看下回分解~

举报

相关推荐

0 条评论