ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessor,所以他是 BeanFactory 的后置处理器的一种,也是十分重要的一个 BeanFactory 的后置处理器。咱们看看他到底做了哪些事件。
BeanFactoryPostProcessor 的流程程序咱们曾经讲过了,咱们当初从 ConfigurationClassPostProcessor 的 postProcessBeanDefinitionRegistry 办法开始看。
这个办法有两个事件,一个是 registriesPostProcessed 增加了 registryId,这个是前面用于 postProcessBeanFactory 办法中判断是否曾经执行了 processConfigBeanDefinitions 办法。这里必定会执行,所以 postProcessBeanFactory 办法就不再执行。
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 其余略
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
processConfigBeanDefinitions 办法是比拟外围的办法,我这里就不贴很多代码,通过流程图的形式解说这里做了什么。具体的例子参考之前的文章 spring 学习之 bean 的定义。
@Configuration
首先,他会获取 @Configuration 注解,他实际上是继承了 @Component。而后再解析 @Configuration 类中的其余注解。所以咱们常常在类上写的 @Configuration 之所以会注入到容器中,就是这里被解析的。
解析的过程是在 ConfigurationClassParser 的 parser 办法中,解析的后果存入 BeanDefinition。parser 最初调用比拟重要的办法是 doProcessConfigurationClass。
@Conditional
doProcessConfigurationClass 办法是在 processConfigurationClass 办法中调用的,processConfigurationClass 办法中有一个比拟重要的注解判断,@Conditional,用于判断是否存入 BeanDefinition。咱们罕用的 @ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnClass、@ConditionalOnMissingClass、@Conditional 等就是 ConditionEvaluator#shouldSkip 办法来判断的,如果符合条件,才能够解析上面的几个注解。
@PropertySource
咱们须要引入资源配置文件的时候,常常用以下的写法,他能被注入到各个属性,就是在 doProcessConfigurationClass 这个办法中实现的。
@Configuration
@PropertySource("classpath:***.properties")
public class XXXConfig {}
@ComponentScans 和 @ComponentScan
这两个注解的 basePackages 上面的类,就是这里在这里扫描,因为可能扫描的类中,也有这两个注解,所以这个办法里会通过递归调用 parse 办法。
Import
spring 学习之 bean 的定义
在这里演示了 import 的三种形式,包含 @Import 注解、实现 ImportBeanDefinitionRegistrar 接口、实现 ImportSelector。这三种为什么能被注入容器,就是在 ConfigurationClassParser 的 processImports 办法解析。
首先是解析 ImportSelector 接口,而后是 ImportBeanDefinitionRegistrar 接口,最初是
@Import 注解。
@ImportResource
当咱们须要引入其余的 spring 配置文件时,咱们会用 @ImportResource 注解,也是在这里解析的。
@ImportResource({"classpath *:XXX.xml"})
public class MyConfig {}
@Bean
最初是 @Bean,咱们在代码里注入的 bean 的定义。
所以 ConfigurationClassPostProcessor 其实做了很多事件,下面几个注解会把解析后的信息退出到 BeanDefinition,前面 getBean 的时候,就会调用这里 BeanDefinition 的内容。
整体流程