下面翻译自spring官网
使用BeanFactoryPostProcessor自定义配置元数据
我们要查看的下一个扩展点是org.springframework.beans.factory.config.BeanFactoryPostProcessor。此接口的语义与BeanPostProcessor类似,但有一个主要区别:BeanFactoryPostProcessor操作bean配置元数据。也就是说,Spring IoC容器允许BeanFactoryPostProcessor在容器实例化BeanFactoryPostProcessor实例之外的任何bean之前读取配置元数据并可能更改它。
您可以配置多个BeanFactoryPostProcessor实例,并且您可以通过设置order属性来控制这些BeanFactoryPostProcessor实例运行的顺序。但是,您只能在BeanFactoryPostProcessor实现了有序接口的情况下设置此属性。如果您编写自己的BeanFactoryPostProcessor,也应该考虑实现Ordered接口
如果希望更改实际bean实例(即从配置元数据创建的对象),则需要使用BeanPostProcessor(在前面通过使用BeanPostProcessor自定义bean中进行了描述)。虽然在BeanFactoryPostProcessor中使用bean实例在技术上是可行的(例如,通过使用BeanFactory.getBean()),但是这样做会导致过早的bean实例化,违反标准的容器生命周期。这可能会导致负面的副作用,比如绕过bean的后处理。
另外,BeanFactoryPostProcessor实例的作用域为每个容器。这只有在使用容器层次结构时才有用。如果您在一个容器中定义了BeanFactoryPostProcessor,那么它只应用于该容器中的bean定义。一个容器中的Bean定义不会被另一个容器中的BeanFactoryPostProcessor实例进行后处理,即使这两个容器属于同一层次结构。
当bean工厂后处理器在ApplicationContext中声明时,它将自动运行,以便对定义容器的配置元数据应用更改。Spring包括许多预定义的bean工厂后处理器,如PropertyOverrideConfigurer和PropertySourcesPlaceholderConfigurer。您还可以使用自定义BeanFactoryPostProcessor—例如,用于注册自定义属性编辑器。
ApplicationContext自动检测部署到其中实现BeanFactoryPostProcessor接口的任何bean。在适当的时候,它将这些bean用作bean工厂的后处理器。可以像部署任何其他bean一样部署这些后处理bean。
与BeanPostProcessors一样,您通常不希望将BeanFactoryPostProcessors配置为延迟初始化。如果没有其他bean引用bean(工厂)后处理器,则该后处理器根本不会实例化。因此,将它标记为延迟初始化将被忽略,并且即使在声明您的Bean />时将default-lazy-init属性设置为true, Bean(工厂)后处理器也将被快速实例化。元素。
让我们看下BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor两个接口因为他们会贯穿invokeBeanFactoryPostProcessors方法的执行逻辑
/**
* 允许自定义修改应用程序上下文的Bean定义,调整上下文的基础Bean工厂的Bean属性值。
* 应用程序上下文可以在它们的bean定义中自动检测BeanFactoryPostProcessor bean,并在创建任何其他bean之前应用它们。
* 对于针对系统管理员的自定义配置文件很有用,这些文件覆盖了在应用程序上下文中配置的Bean属性。
* 请参阅PropertyResourceConfigurer及其具体实现,以了解解决此类配置需求的即用型解决方案。
* BeanFactoryPostProcessor可以与bean定义进行交互并对其进行修改,但不能与bean实例进行交互。这样做可能会导致bean 实例化过早,
* 从而违反了容器并造成了意想不到的副作用。
*/
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* 在标准初始化之后,修改应用程序上下文的内部bean工厂。所有bean定义都将被加载,但是还没有实例化bean。
* 这甚至可以覆盖或添加属性,甚至可以用于初始化bean。
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
/**
* 对标准BeanFactoryPostProcessor SPI的扩展,允许在常规之前在之前注册更多的bean定义BeanFactoryPostProcessor检测开始。
* 尤其是 BeanDefinitionRegistryPostProcessor可以注册更多的Bean定义反过来定义BeanFactoryPostProcessor实例。
*/
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* 在标准初始化之后,修改应用程序上下文的内部bean定义注册表。所有常规bean定义都将已加载,但尚未实例化任何bean。
* 这允许在下一个后处理阶段开始之前添加更多的 bean定义。
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
这里可以看出来两个方法的区别:
一个是所有常规bean定义都将被加载
一个是所有常规bean定义都将已加载。
一个是已完成一个是进行中,可以稍微理解后面两个方法的执行顺序
解析invokeBeanFactoryPostProcessors方法
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//首先调用BeanDefinitionRegistryPostProcessors(如果有)。
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 保存只实现了BeanFactoryPostProcessor接口的后处理器
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 保存只实现了BeanDefinitionRegistryPostProcessor接口的后处理器
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
/**
* 执行实现了BeanDefinitionRegistryPostProcessor接口的后处理器的
* postProcessBeanDefinitionRegistry方法,
* 注意这里执行的不是postProcessBeanFactory方法
*/
registryProcessor.postProcessBeanDefinitionRegistry(registry);
/**
* 保存执行过了的BeanDefinitionRegistryPostProcessor,
* 这里执行过的BeanDefinitionRegistryPostProcessor只是代表它的特有方法:
* postProcessBeanDefinitionRegistry方法执行过了,
* 但是千万记得,它还有一个标准的postProcessBeanFactory,也就是从父接口中继承的方法还未执行
*/
registryProcessors.add(registryProcessor);
}
else {
// 将只实现了BeanFactoryPostProcessor接口的后置处理器加入到集合中
regularPostProcessors.add(postProcessor);
}
}
/**
* 不要在这里初始化FactoryBeans:我们需要保留所有未初始化的常规beans
* 以便让bean工厂后处理器对其应用! 将实现 PriorityOrdered,Ordered和
* 其余的BeanDefinitionRegistryPostProcessor分开。
*/
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessor。
// 从容器中获取到所有实现了BeanDefinitionRegistryPostProcessor接口的Bean的名字
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//如果当前Bean实现了 PriorityOrdered 这个接口,则当前 Bean 会被最优先调用。
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
/**
* 给currentRegistryProcessors排序
*/
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 将当前将要执行的currentRegistryProcessors全部添加到registryProcessors这个集合中
registryProcessors.addAll(currentRegistryProcessors);
/**
* 循环调用 postProcessBeanDefinitionRegistry方法
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
/**
* 清除当前的RegistryProcessors
*/
currentRegistryProcessors.clear();
// 接下来,调用实现Ordered的BeanDefinitionRegistryPostProcessors。
/**
* 如果当前 Bean 实现了 Ordered 接口,则当前 Bean 会被作为第二优先级调用:
*/
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
/**
* 判断一下processedBeans是否有
* 当前的postProcessorName防止重复执行
*/
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
/**
* 最后,调用所有其他BeanDefinitionRegistryPostProcessor,直到不再出现。
* 所有常规bean定义都将已加载。(进行中)
* 所以需要循环执行
*/
boolean reiterate = true;
while (reiterate) {
reiterate = false;
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();
}
// 现在,调用到目前为止已处理的所有处理器的postProcessBeanFactory回调。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
// 调用在上下文实例中注册的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 不要在这里初始化FactoryBeans:我们需要保留所有常规bean
// 未初始化,让Bean工厂后处理器对其应用!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
/**
* 在实现PriorityOrdered的BeanFactoryPostProcessor之间分开,
* Ordered 还有其余的。
*/
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// 跳过-已在上面的第一阶段处理
}
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的BeanFactoryPostProcessors。
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
//接下来,调用实现Ordered的BeanFactoryPostProcessors。
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
//最后,调用所有其他BeanFactoryPostProcessors。
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
/**
* 清除缓存的合并bean定义,因为后处理器可能已经修改了原始元数据,例如替换值中的占位符...
*/
beanFactory.clearMetadataCache();
}