BeanFactoryPostProcessor
BeanFactoryPostProcessor:beanFactory 的后置处理器
beanFactory 标准初始化之后调用;所有bean已经保存到beanFactory,但是bean 实例还未创建
编写一个MyBeanFactoryPostProcessor
测试类
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("=======================MyBeanFactoryPostProcessor");
int count = beanFactory.getBeanDefinitionCount();
String[] names = beanFactory.getBeanDefinitionNames();
System.out.println("当前beanfactory有"+count+"个bean");
Arrays.asList(names).stream().forEach(System.out::println);
}
}
配置类
@Configuration
@ComponentScan("com.funtl.hello.spring.cloud.eureka.postprocessor")
public class ExtConfig {
}
测试类
public class TestSpringExt {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
applicationContext.close();
}
}
启动容器控制台打印如下
=======================MyBeanFactoryPostProcessor
当前beanfactory有11个bean
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
extConfig
cat
dog
myBeanFactoryPostProcessor
myBeanPostProcessor
上面的11 个bean都只是bean定义信息并没有创建对象实例。我们在MyBeanFactoryPostProcessor
的postProcessBeanFactory
方法打个断点
查看方法调用栈
我们进入选中处的伪代码分析
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors)
//这里就是获得所有BeanFactoryPostProcessor 类型的bean名称(编译的时候已经将所有类信息放到常量池中,所以只要编译就会有类信息,但是并灭有创建对象)
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
for (String postProcessorName : nonOrderedPostProcessorNames) {
//getBean 方法就是 根据class 信息通过反射创建bean 实例,其中又会经过一系列的前置后置方法初始化方法等。
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}
进入invokeBeanFactoryPostProcessors()
方法我们就会发现很简单这里就是调用 所有BeanFactoryPostProcessor
的postProcessBeanFactory()
方法
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//这里是创建BeanFactoryPostProcessors 对象
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//这里是创建 BeanPostProcessors 对象
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//这里才是执行剩下的所有bean 创建bean 实例对象
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
}
}
整个过程
- ioc容器创建对象
-
invokeBeanFactoryPostProcessors(beanFactory);
- 直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
- 在执行初始化创建其他组件前面执行
BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor接口,并且增加了一个postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
方法。
在所有bean 定义信息将要加载,bean实例还未创建;优先于BeanFactoryPostProcessor
执行
利用BeanDefinitionRegistryPostProcessor
给容器中额外添加组件
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
创建一个MyBeanDefinitionRegistryPostProcessor
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("postProcessBeanDefinitionRegistry++++++++bean的数量" +registry.getBeanDefinitionCount());
// RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Person.class);
AbstractBeanDefinition rootBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
registry.registerBeanDefinition("person",rootBeanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("postProcessBeanFactory++++++++bean的数量" +beanFactory.getBeanDefinitionCount());
}
}
控制台输出
postProcessBeanDefinitionRegistry++++++++bean的数量12
postProcessBeanFactory++++++++bean的数量13
分析一下先执行postProcessBeanDefinitionRegistry()
方法 现在有12 个bean定义信息,再执行postProcessBeanFactory
有13个bean 定义信息加了一个person
在MyBeanDefinitionRegistryPostProcessor
打一个断点
再分析方法调用栈
发现和
MyBeanFactoryPostProcessor
的调用过程一样。我们进入相同的方法列出一段伪代码
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
这段伪代码在上面那段伪代码之前执行,所以这也就解释了为什么先执行postProcessBeanDefinitionRegistry
再执行postProcessBeanFactory
过程
- ioc 创建对象
-
refresh()
->invokeBeanFactoryPostProcessor(beanFactory)
; - 从容器中获取到所有
BeanDefinitionRegistryPostProcessor
组件
1. 依次触发所有postProcessorBeanDefinitionRegistry()
方法
2. 再来触发postProcessorBeanFactory()
方法