Spring:@Configuration注解的类的加载实现原理

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!

Spring:@Configuration注解的类的加载实现原理


概述


这里主要分析@Configuration注解的类自身的加载的实现,即生成该类对应的BeanDefinition,注册到BeanFactory,此时该类就跟一个普通使用了如@Component注解的类一样,是在创建和初始化BeanFactory的过程中完成的。而@Configuration注解的处理是通过ConfigurationClassPostProcessor来完成的,ConfigurationClassPostProcessor是一个BeanFactoryPostProcessor接口实现类。

    

以下先从我们熟悉的@Configuration注解的处理实现说起,然后再回过头来分析在执行@Configuration的注解处理之前,@Configuration注解的类是怎么注册到BeanFactory中的。通俗来说,就以先分析怎么煎鸡蛋,再分析这个鸡蛋怎么被母鸡生出来的思路来分析。


@Configuration的注解处理器ConfigurationClassPostProcessor的创建


  • AnnotationConfigBeanDefinitionParser是的标签处理器。

  • AnnotationConfigBeanDefinitionParser会调用AnnotationConfigUtils.registerAnnotationConfigProcessors方法;

  • 如果Spring容器所使用的ApplicationContext接口实现类为AnnotationConfigApplicationContext,则也会调用这个方法

  • AnnotationConfigUtils.registerAnnotationConfigProcessors方法的执行,会注册三个注解处理器,分别是:


    1.ConfigurationClassPostProcessor:BeanFactoryPostProcessor接口的实现类,处理@Configuration,@Component,@ComponentScan,@Import,@ImportResource或@Bean注解。

    2.AutowiredAnnotationBeanPostProcessor:BeanPostProcessor接口实现类,处理@Autowired注解。

    3.CommonAnnotationBeanPostProcessor:BeanPostProcessor接口实现类,处理JDK提供的注解,如@PostConstruct,@PreDestroy,@Resource等。

        PersistenceAnnotationBeanPostProcessor(使用JPA的时候)


@Configuration注解的类的加载


ConfigurationClassPostProcessor为BeanFactoryPostProcessor,此时是从BeanFactory获取已经创建好的BeanDefinition,检测每个BeanDefinition对应的类上面是否使用了以上四个注解。所以在基于注解的配置设计中,对应的类怎么才能生成对应的BeanDefinition注册到BeanFactory,之后才能被ConfigurationClassPostProcessor处理?如果是基于XML的,一般会在applicationContext.xml中通过注解或者bean标签,获取到了相关的BeanDefinition。

    

其实@Configuration注解的作用是作为一个配置类,对应类内部使用@Bean注解方法,则该方法会作为BeanDefinition注册到BeanFactory中。以及扫描一起使用的@ComponentScan注解指定的类或包,获取对应的BeanDefinition。


Spring容器ApplicationContext


但是对于Spring容器而言,即ApplicationContext接口的实现类,既可以是基于XML的XmlApplicationContext,即使用applicationContext.xml来作为配置,也可以是基于JavaConfig,如实现WebApplicationInitializer接口,在这个接口的onStartup方法中,指定特定的ApplicationContext,一般为AnnotationConfigApplicationContext,并指定使用了@Configuration注解的配置类,作为AnnotationConfigApplicationContext的构造函数参数值。所以针对这两种方式,分别说明如何使@Configuration注解的类,先作为BeanDefinition注册到BeanFactory,然后再被ConfigurationClassPostProcessor处理其上的注解。

        

基于applicationContext.xml:使用标签,并在base-package属性指定的@Configuration类所在的包,则Spring容器启动时,就会加载@Configuration注解类并创建BeanDefinition对象注册到BeanFactory中,之后ConfigurationClassPostProcessor作为BeanFactoryPostProcessor,从BeanFactory取出并赛选使用了@Configuration注解的类对应的的BeanDefinition,处理其上的@ComponentScan等注解和类内部使用@Bean注解的方法。

        

基于JavaConfig的方式,在WebApplicationInitializer接口实现类的onStartup方法中,以@Configuration注解的类作为构造函数参数,创建AnnotationConfigApplicationContext对象,然后交给该对象以attribute方式添加到ServletContext中。此时AnnotationConfigApplicationContext在内部会使用AnnotatedBeanDefinitionReader注册这个使用了@Configuration注解的配置类到BeanFactory中。之后ConfigurationClassPostProcessor完成与基于applicationContext.xml的方式中一样的处理。

        

SpringBoot的处理方式:SpringBoot的SpringApplication使用AnnotationConfigApplicationContext作为Spring容器的ApplicationContext,然后将main方法所在启动类作为参数调用SpringApplication.run方法,其中该启动类为一个基于注解的配置类,一般为@SpringBootApplication注解或者@Configuration注解等。SpringApplication初始化启动时,与基于JavaConfig的方式一样,也是通过AnnotatedBeanDefinitionReader来将启动类作为BeanDefinition注册到BeanFactory的,之后使用ConfigurationClassPostProcessor来处理相关注解。



原文链接:https://blog.csdn.net/u010013573/java/article/details/86686153



精彩推荐

Spring的Assert断言使用

浅谈spring aop的五种通知类型

Spring核心配置文件详解

多个事务同时存在,Spring如何处理这些事务?



扫下方二维码关注“程序员考拉”,每日推荐优秀好文!



Spring:@Configuration注解的类的加载实现原理


如果感觉推送内容不错,不妨右下角点个在看,感谢支持!

原文始发于微信公众号(程序员考拉):Spring:@Configuration注解的类的加载实现原理