概述
在 Spring - IoC 容器之拓展点 BeanPostProcessor 这篇文章中讲解了 BeanPostProcessor
的作用和原理,是在 Bean
的初始化前后进行拦截工作。而 BeanFactoryPostProcessor
在功能上有点类似,我们来看一下源码:
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;
}
从源码注释中我们了解到,BeanFactoryPostProcessor
的拦截时机是在 ApplicationContext
的标准初始化之后调用的,可以用来修改 bean definition registry
中的 bean definition
信息,这时候所有的 BeanDefinition
已经加载进 BeanFactory
了,但是还没有初始化。
举例
自定义 BeanFactoryPostProcessor
的实现类:
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("invoke my bean post factory post processor.................");
int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
System.out.println("当前BeanFactory中有:" + beanDefinitionCount + " 个BeanDefinition");
}
}
@Configuration
@ComponentScan("com.keke.ext")
// 导入一个 Bean,并自定了初始化方法(参考:https://blog.youkuaiyun.com/qiaohao0206/article/details/125876005)
@Import(Car.class)
public class ExtConfig {
}
初始化 IoC 容器
,并输出容器中的 Bean
:
invoke my bean post factory post processor.................
当前BeanFactory中有:7 个BeanDefinition
car init by @PostConstruct
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
extConfig
myBeanFactoryPostProcessor
从输出结果可以看出,BeanFactoryPostProcessor
的执行时机是在 Bean
的初始化之前调用的,并且这时候 BeanFactory
中已经有了 BeanDefinition
。
原理
我们来看一下 IoC
容器 AnnotationConfigApplicationContext
的初始化过程:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
// 核心流程
refresh();
}
接着查看 refresh()
方法:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
...
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// 这里就是调用 BeanFactoryPostProcessor 的核心流程
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// 这里注册 BeanPostProcessor
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
...
// 这里是完成初始化 Bean 的流程
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
...
}
}
查看 invokeBeanFactoryPostProcessors()
方法:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 核心流程
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
...
}
接着查看 PostProcessorRegistrationDelegate
中的 invokeBeanFactoryPostProcessors()
方法:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
...
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
// 1、这里获取所有类型为 BeanFactoryPostProcessor 的 Bean
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 2、排序并调用
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 3、核心流程
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
...
}
查看 invokeBeanFactoryPostProcessors()
方法:
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
// 执行具体的 postProcessBeanFactory 流程
postProcessor.postProcessBeanFactory(beanFactory);
}
}