概要:ConfigurationClassPostProcessor 是 spring 中极为重要的一个类尤其是在 springboot 广泛应用的背景下,ConfigurationClassPostProcessor 类 在spring 容器启动流程之初 收集 @Configuration 注解的类以及 @Component @ComponentScan @Import @ImportResource 和 @Bean 将其封装成BeanDefinition 注册到spring registry中,以备后期的实例化。
1. AnnotationConfigApplicationContext 构造函数中 三步走
(1) this() 用于注册 两个类 AnnotatedBeanDefinitionReader ClassPathBeanDefinitionScanner
(2)setConfig(location / configclass) 用于配置项目的基础扫描路径
(3)refresh() 调用AbstractApplicationContext 的 refresh() 方法 改方法 就是spring和核心路程方法(spring的流程模板)
AnnotatedBeanDefinitionReader 注册几个BeanRegistryPostProcessor ConfigurationClassPostProcessor / AutowiredAnnotationBeanPostProcessor / CommonAnnotationBeanPostProcessor
以及事件等的一些类。
invokeBeanFactoryPostProcessor(beanFactory) -> 实例化 ConfigurationClassPostProcessor -> invokeBeanDefinitionRegistrPostProcessors()
-> ConfigurationClassPostProcessor . postProcessBeanDefinitionRegistry . processConfigBeanDefinitions
在processConfigBeanDefinitions()中 首先收集 上面描述的注解的类 装入集合遍历解析 引出 ConfigurationClassParser 类进行解析
ConfigurationClassParser 解析 parse() 使用方法的递归进行循环的遍历
@ComponentScan 注解定义的包类会被扫描后封装成BeanDefinition 注册到 BeanDifinitionRegistry 中待实例化。
@PropertyResource 中的配置项 会被包装成 PropertyResource 添加到 Environment 的 MutablePropertySources 类型的变量中
@Import 导入的类 ImportSelector(DeferredImportSelector) / ImportBeanDefinitionRegistrar 会被收集到 不同的容器中后面 beanDefinition的注册
ImportSelector 接口 selectImports() 方法返回的是 String 类型的数组 String字符串必须是 类的全限定名
ImportBeanDefinitionRegistrar 提供了默认的方法给子类实现 registryBeanDefinitions (meta , registry) 实现BeanDefinition 增删改操作
@Bean 注解方法收集到 宿主类的 method的集合
@ImportResource 等以及 当前配置类的 父类的扫描
收集完成后 ConfigurationClassBeanDefinitionRender 进行 beanDefinition 的封装和注册
(1)配置类本身注册
(2) @Bean 方法的注册
实现 通过factoryMethod 实现的,每一个@Bean 注册成一个 ConfigurationClassBeanDefinition类型的 BeanDefinition 通过设置改 BeanDefinition的 factoryMethod 和 factoryBeanName / BeanClassName 等属性来为后期 @Bean的实例化作准备。
重点2 》》》 ConfigurationClassPostProcessor implements BeanFactoryPostProcessor
特征方法 postProcessBeanFactory(beanFactory.) 对 @Configuration 类型 (full 类型) 的 BeanDefinition 进行 增强处理
enhanceConfigurationClasses(beanFactory)
遍历所有spring管理的的BeanDefinition 收集 full ,使用CGLIB生成代理类型的 子类 并设置 为 @Configuraion的 BeanDefinition的 BeanClass
涉及的核心类:
(1) ConfigurationClassPostProcessor 作为注解形式beanDefinition 注册到Spring的入口
a> BeanDefinitionRegistryPostProcessor . postProcessBeanDefinitionRegistry(registry) 收集并注册BeanDefinition到spring
b> BeanFactoryPostProcessor postProcessBeanFactory(beanFactory) 对 @Confiuguration 即 full 类型 并且 有@Bean 类型的方法 进行生成增强的 BeanClass 字节码的子类型并设置为 @Configuration BeanDefinition的BeanClass
(2)ConfigurationClassParser 进行解析收集
ConfigurationClassBeanDefinitionRender loadBeanDefinition()进行BeanDefinition的注册
ConfigurationClassBeanDefinition @Bean 方法注册的bean的BeanDefinition的类型
ConfigurationClassEnhancer @Configuration的增强类型 使用CGLIB 生成的字节码类的子类
(3)实例化 CallBackFilter 拦截类 分 3 个
a> BeanMethodInterceptor
切面通知:
(1) 拦截 FactoryBean 拦截 getObject() 方法,通过 beanFactory.getBean() 尝试从缓存中获取类的实例对象,防止了 @Configuration 配置类中 @Bean 类型的方法相互调用产生多个不同的实例
(2) @Bean factoryMethod 直接反射调用即可
b> BeanFactoryAwareMethodInterceptor
c> NoOp.INSTANCE
NoOp.INSTANCE
源码位置: