BeanFactoryPostProcessor支持对IoC容器内部的所有BeanDefinition进行定制化修改, 并且可以根据IoC容器内部的BeanFactory进行Bean属性值的适配。
也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置’order’属性来控制各个BeanFactoryPostProcessor的执行次序。
本节主要介绍一下BeanFactoryPostProcessor的简单使用及其原理。
注:可以用BeanFactoryPostProcessor修改BeanDefinition,但是千万不要出来Bean的实例化,否则可能导致Bean被过早地实例化出来,污染IoC容器,造成潜在的危险。
创建自定义BeanFactoryPostProcessor实例:
public class SimpleBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.err.println("BeanDefinitionCount: " + beanFactory.getBeanDefinitionCount());
System.err.println("BeanDefinitionNames: " + Arrays.asList(beanFactory.getBeanDefinitionNames()));
}
}
创建配置类,注册SimpleBeanFactoryPostProcessor和自定义Bean:
@Configuration
@ComponentScan
public class MainConfig {
@Bean
public SimpleBeanFactoryPostProcessor simpleBeanFactoryPostProcessor(){
return new SimpleBeanFactoryPostProcessor();
}
@Bean
public Blue blue(){
return new Blue();
}
}
加载Ioc容器,可以看到控制台打印,先进行BeanFactoryPostProcessor的处理,再实例化Bean。
BeanDefinitionCount: 19
BeanDefinitionNames: [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, mainConfig, org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor, org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor, cat, userDao, simpleCalculator, calculatorAspect, applicationContextHolder, userController, userService, blue, simpleBeanFactoryPostProcessor, org.springframework.aop.config.internalAutoProxyCreator]
Construct Blue
下面结合源码分析BeanFactoryPostProcessor的工作流程:
首先看BeanFactoryPostProcessor接口,其定义十分简单,只有一个方法,进行BeanFactory初始化后的处理:
public interface BeanFactoryPostProcessor {
//拦截IoC容器内部的BeanFactory的标准初始化过程,该方法在所有BeanDefinition加载完毕,且Bean实例创建之前调用。
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
BeanFactoryPostProcessor的调用在IoC容器的refresh()方法中:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//刷新前的准备
prepareRefresh();
//刷新IoC容器内部的BeanFactory,并加载BeanDefinition
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
//调用BeanFactoryPostProcessor处理
invokeBeanFactoryPostProcessors(beanFactory);
//向容器中注册BeanPostProcessor后处理器
registerBeanPostProcessors(beanFactory);
//初始化消息源
initMessageSource();
//初始化事件分发器
initApplicationEventMulticaster();
onRefresh();
//初始化事件监听器
registerListeners();
//实例化所有非lazy的单实例Bean
finishBeanFactoryInitialization(beanFactory);
//刷新完成
finishRefresh();
}
}
}
调用BeanFactoryPostProcessor的处理在invokeBeanFactoryPostProcessors()方法中。可以看到该方法在obtainFreshBeanFactory()加载BeanDefinition后,在finishBeanFactoryInitialization()实例化Bean之前。
调用BeanFactoryPostProcessor的核心逻辑在PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法中:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//如果存在BeanDefinitionRegistryPostProcessor,则首先调用如果存在BeanDefinitionRegistryPostProcessor处理
Set<String> processedBeans = new HashSet<String>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
registryPostProcessors.addAll(priorityOrderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(beanFactory, orderedPostProcessors);
registryPostProcessors.addAll(orderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
registryPostProcessors.add(pp);
processedBeans.add(ppName);
pp.postProcessBeanDefinitionRegistry(registry);
reiterate = true;
}
}
}
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//首先,调用实现了PriorityOrdered接口的BeanFactoryPostProcessor
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
//然后,调用实现了Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(beanFactory, orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
//最后,调用所有其他的BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}
可以看到,该方法首先将实现了顺序接口的BeanFactoryPostProcessor进行排序,然后按照顺序依次调用,调用的处理在invokeBeanFactoryPostProcessors()方法中:
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
该方法十分简单,即遍历所有的BeanFactoryPostProcessor实例,依次调用其postProcessBeanFactory()方法。