@Bean前置知识
1 需要再Configuration Class中才能被解析
2 静态@Bean也就是标注在static方法上的 实例@Bean标注在普通方法上的
所有的Bean在创建之前都会变成BeanDefinition,其中有这样两个属性:
setFactoryMethodName:静态方法
setFactoryBeanName:指定工厂Bean名称
处理流程
首先在创建上下文的时候,这里面做了两件事情:
1 创建了reader
2 创建了scanner
其中reader会去注册ConfigurationClassPostProcessor:
而scanner会去扫包下的配置类@Configuration,在扫描的时候是通过includeFilters去实现的:
因为我们的@Configuration其实继承了@Component
那么完成了@Configuration扫描以后@Bean怎么处理转换为BeanDefinition呢?
它的处理依赖于ConfigurationClassPostProcessor
然后再processConfigBeanDefinitions里面通过ConfigurationClassParser进行操作:
跟踪源码到下面这个方法,里面会有递归的扫描,也就是处理Configuration里面嵌套:
然后标注了@Bean的就会被取出来封装成为MethodMetadata:
然后MethondMetadata方法转换为BeanDefinition:
进入loadBeanDefinitionsForBeanMethod这个方法,里面有个非常重要的判断逻辑,如果是静态的直接设置BeanClass和方法名:
如果是实例方法则设置FactoryBeanName。
这两个的区别是static直接调用方法所以它的加载不依赖于Configration的Bean实例,普通实例方法依赖于Configration这个配置类,也就是Configration这个类先要变为Bean然后进行普通方法@Bean的处理。
这里还需要注意ConfigurationClassPostProcessor的优先级是优先里面最低的(也就是要优先处理,但是处理的优先尽量靠后)。
然后PostProcessor怎么生效的其实就是在容器刷新的时候去主动调用的:
上面的调用对应了:
postProcessBeanDefinitionRegistry
下面的调用对应了:
postProcessBeanFactory