持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情
invokBeanDefinitionRegistryPostProcessor方法解析
-
循环实现了BeanDefinitionRegistryPostProcessor的后置处理器,调用它的postProcessBeanDefinitionRegistry(注册器)方法处理class;这里就是配置类后置处理器的实现
-
获取容器中目前所有的beandefinition的name,循环这个数组,根据名称从registry中获得beandefinition对象,在解析之前先判断当前类是不是解析过,判断是一个完全配置类(full)还是lite配置类;
full跟lite的判断标准:
Configuration注解的即为完全配置类,标记成full;
Component,ComponentScan Import ImportResource 注解的为lite配置类,标记lite;
-
满足了上述的配置类的条件就把相关的beanDefinition对像丢到configCandidates集合里面去;根据order接口在排个序;
-
判断一下当前传入的注册器,是不是单例注册,然后继续执行;
-
先创建@CompentScan注解和@Import注解导入的bean的名称的生成器;
-
parser.parse(candidates)解析配置类(这里的配置类就是满足上面条件筛选下来的,也即是我们传入的配置类)
解析
首先是声明了一个延时导入选择器的集合 this.deferredImportSelectors = new LinkedList<>();
比如Springboot的自动装配的类AutoConfigurationImportSelector;
-
真正解析配置的方法doProcessConfigurationClass
-
先处理@propertySource注解的类:
-
@ComponentScan
这里会把当前注解包含的类解析成bean定义存起来,循环处理这些解析出来的新的benadefinition,判断其中有没有配置类,有的话则再次递归调用parse解析方法,在重走一遍;
在这里会创建一个ClassPathBeanDefinitionScanner扫描器 扫描符合条件的类;
-
@Import注解
循环import注解导入的所有组件,判断是否实现了ImportSelector,是的话就实例化当前ImportSelector,在判断是不是延时DeferredImportSelectors,是的话则暂时不作处理,放到最开始解析的延时导入选择器的集合中;不是延时的则递归解析成普通使用的组件;
-
@ImportResource
-
@Bean
从上而下依次解析;
-
-
解析完成,得到一个集合类,然后把这些类加载到bean定义,注册到BeanDefinitionMap中;
上述为大概文字描述的invokBeanDefinitionRegistryPostProcessor的实现;
invokeBeanFactoryPostProcessors在加载逻辑上跟上述差不多,不同的在于多了一行 enhanceConfigurationClasses(beanFactory) 使用cglib对配置类进行代理,@Bean方法需要使用实例化;
说明:只有标记了full的类才会创建cjlab动态代理,如果不加注解,当我们使用@bean在配置类中使用另外一个bean,这个时候会重复加载这个bean ,使用了@Configuration注解会创建动态代理,当使用@Bean的时候,先会检查是否加载过该bean;