在idea中搜索了一下Spring的后置处理器(PostProcessor),找出了下图的几个
本文主要来分析红框中标出的两个,也就是在 refresh()
方法的第5步调用的后置处理器
1、后置处理器调用的时机
2、后置处理器调用的顺序
3、一个最重要的后置处理器
这个最重要的后置处理器就是 ConfigurationClassPostProcessor
1、ConfigurationClassPostProcessor的作用?
2、
4、案例读源码
(1)案例1
(2)案例2
(3)案例3
Spring Cloud中的案例一个,大家对Spring Cloud不熟悉没有关系,只需要关注Spring Framework部分就可以了
下面的代码是个 org.springframework.cloud.netflix.feign.ribbon包下的一个配置类(@Configuration),大家忽略Spring Cloud,就把它看做就是一个普通的配置类
@Configuration
class DefaultFeignLoadBalancedConfiguration {
@Beand
@ConditionalOnMissingBean
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory) {
return new LoadBalancerFeignClient(new Client.Default(null, null),
cachingFactory, clientFactory);
}
}
下面启动时,我们在下面的方法上打上条件断点:org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass
调用栈如下
loadBeanDefinitionsForConfigurationClass:140, ConfigurationClassBeanDefinitionReader (o.s.context.annotation)
loadBeanDefinitions:116, ConfigurationClassBeanDefinitionReader (o.s.context.annotation)
processConfigBeanDefinitions:320, ConfigurationClassPostProcessor (o.s.context.annotation)
postProcessBeanDefinitionRegistry:228, ConfigurationClassPostProcessor (o.s.context.annotation)
invokeBeanDefinitionRegistryPostProcessors:272, PostProcessorRegistrationDelegate (o.s.context.support)
invokeBeanFactoryPostProcessors:92, PostProcessorRegistrationDelegate (o.s.context.support)
invokeBeanFactoryPostProcessors:687, AbstractApplicationContext (o.s.context.support)
refresh:525, AbstractApplicationContext (o.s.context.support)
refresh:122, EmbeddedWebApplicationContext (o.s.boot.context.embedded)
refresh:693, SpringApplication (o.s.boot)
refreshContext:360, SpringApplication (o.s.boot)
run:303, SpringApplication (o.s.boot)
run:1118, SpringApplication (o.s.boot)
run:1107, SpringApplication (o.s.boot)
main:21, AppBMain (com.yh.stu)
几种注册BD的方式
1、硬编码
通过BeanDefinitionRegistry.registerBeanDefinition硬编码的方式进行注册,通常的做法有:
1、Spring 本身在实例化AnnotationConfigApplicationContext时,根据环境情况硬编码注册4~7个BD
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
...
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {
...
// 共注册了6个BD,即使通过
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
...
}
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
我这里列出几个大家有个印象,后续用到这几个BD的时候知道怎么来的就可以了。
// 实现了两个接口:BeanDefinitionRegistryPostProcessor/BeanFactoryPostProcessor
1:org.springframework.context.annotation.ConfigurationClassPostProcessor
// 实现了BeanPostProcessor、BeanFactoryAware、PriorityOrdered接口
2:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
// 同2一样,实现了BeanPostProcessor、BeanFactoryAware、PriorityOrdered接口
3:org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
// 同2一样,实现了BeanPostProcessor、BeanFactoryAware、PriorityOrdered接口
4:org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
// 实现了SmartInitializingSingleton, ApplicationContextAware 接口
5:org.springframework.context.event.EventListenerMethodProcessor
6:org.springframework.context.event.DefaultEventListenerFactory
❓ 1-这些Spring内部的 Bean是什么时候实例化的呢?
❓ 2-自定义的 BeanFacotryPostProcessor 是什么时候实例化的呢?
答1:
(1)、内部BeanFacotryPostProcessor 是在其被调用的时候利用容器(beanFactory.getBean(…))进行实例化的。
(和普通的Bean不一样,普通的Bean都是在refresh的第11阶段,即在finishBeanFactoryInitialization(beanFactory)
方法中进行的)
//org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors){
...
// 从容器中找出所有 BeanDefinitionRegistryPostProcessor 类型的BD,后续按照顺序实例化并调用(PriorityOrdered/Ordered)
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 使用getBean来实例化Bean
currentRegistryProcessors.add(
beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
...
}
(2)、AutowiredAnnotationBeanPostProcessor 是在 refresh的第 6 阶段,即在registerBeanPostProcessors(beanFactory)方法中实例化的
//org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 从容器中找出所有 BeanPostProcessor 类型的BD,后续按照顺序调用(PriorityOrdered/Ordered)
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
...
//遍历到 org.springframework.context.annotation.internalAutowiredAnnotationProcessor
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 使用getBean来实例化Bean
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
}
...
}
(3)同2一样
(4)同2一样
(5)EventListenerMethodProcessor 类的实例化时在refresh() 方法的第 11 阶段,即finishBeanFactoryInitialization(beanFactory) 方法中将其作为普通的Bean进行实例化
2、在容器中配置
Spring中配置Bean,在调用后置处理器 Configuration