文章目录
概览
ConfigurationClassPostProcessor.class
主要解决的问题就是去处理spring定义的一些配置注解,例如@Configuration
,@Import
,@ComponentScan
,@Bean
等。
ConfigurationClassPostProcessor
- 实现了
BeanDefinitionRegistryPostProcessor
(BeanFactoryPostProcessor
的子类)。 PriorityOrdered
,该类优先执行。ResourceLoaderAware
,获取资源加载器。BeanClassLoaderAware
,获取类加载器。EnviromentAware
,获取环境信息。
通过类的实现接口,我们可以大致判断出其主要的处理逻辑在BeanDefinitionRegistryPostProcessor
的实现方法中。
由前面的文章我们能知道,BeanDefinitionRegistryPostProcessor
接口与BeanFactoryPostProcessor
接口的执行顺序是,BeanDefinitionRegistryPostProcessor
优先于BeanFactoryPostProcessor
所以接下来我们先来看看BeanDefinitionRegistryPostProcessor
的方法。
postProcessBeanDefinitionRegistry()
通过注册器获取当前注册器中所有的注册信息。并且找到有@Configuration注解的类。
这里的时间节点非常重要。(这时候只有一些内置类和启动类在注册器中,因此@SpringBootApplication
中必定有@Configuration注解
)。如下图
详见,前面的文章。
parse()
这个方法中就是对@PropertySource
,@ComponentScan
,@Import
,@ImportSource
,@Bean
注解进行解释。
@Component
如果类上面有@Component注解,就扫描类的成员变量所属的类。然后继续这个逻辑。
@PropertySource
对于@PropertySource注解,就是将其信息加载进来,并且放入Enviroment中,位置是在最后(第一个加载的在最后)。
@ ComponentScan,@ComponentScans
解析路径,并扫描路径下的bean。符合规范的就封装成BeanDefinitionHolder(就是有@Component
注解的类,我们在使用中用到的@Service
,@Controller
都继承于@Component
),在后续的步骤中在进行注册。
@Import
- 实现了ImportSelector接口
- 实现了ImportBeanDefinitionRegistrar接口
- 其它
实现ImportSelector
对于实现了ImportSelector
接口的处理方式又分为2类:
- 实现了
ImportSelector
。 - 实现了其子类
DeferredImportSelector()
(这个类由于了解的不深,就不聊了。)
对于1来说,就是执行接口的实现方法selectImports()
,然后继续解析导入的类。
实现ImportBeanDefinitionRegistrar接口
- 实例化该类。
- 并将其添加到自己的集合中(后续加载的时候在进行执行)。
@Bean
- 找到所有有@Bean注解的方法(正常范围内),并将其信息封装成MethodMetadata。
- 将消息放入自己的集合中(后续加载的时候在进行操作)。
到这里,解析工作已经完毕了。后面的就是进行加载了。
load()
这一步就比较简单了,就是将前面一系列准备好的东西进行注册或访问。
前面实现了ImportBeanDefinitionRegistrar
接口的类,触发时间点就是在这里。
postProcessBeanFactory()
- 对由@Configuration注解的类进行增强。
- 添加一个BeanPostProcessor处理器。
先来看看它对@Configuration类做了怎么样的增强。
enhanceConfigurationClasses()
首先找到所有的@Configuration类,然后进行增强。
增强的方式有3种:
BeanMethodInterceptor
BeanFactoryAwareMethodInterceptor
NoOp.INSTANCE
(什么都不处理)
我们先来看看第一种BeanMethodInterceptor
BeanMethodInterceptor
触发条件
类不是Object,并且方法不能是setBeanFactory,并且方法上面有@Bean注解。
作用
- FactoryBean
- 普通Bean
对于1,
将会按照FactoryBean的加载方式进行,也就是通过访问getObject方法,而不是通过从容器中获取。
对于2,
分为2类,第一类就是访问的方法与根方法一致。也就是有自身发起,访问自身。
这种情况,就是直接访问本身方法就行了。
第二类就是由其它方法发起
针对这种情况将会,除了访问本身的方法,还会将createA与createB这两个Bean绑定在一起。
BeanFactoryAwareMethodInterceptor
触发条件
访问的方法是setBeanFactory()
,并且参数只有一个类型为BeanFactory,类实现了BeanFactoryAware。
作用
将BeanFactory对象放到对象中的第一个属性中。(这没搞明白。)
其它就没有操作了。
总结
ConfigurationClassPostProcessor
这类主要就是去处理@Configuration
中的一些配置信息,比如@Import
,@ComponetScan
等。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/121865.html