接口简介
beanfactoryPostProcessor 接口是 Spring 初始化 beanfactory 时对外暴露的扩展点,Spring IoC 容器允许 beanfactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。
BeanDeFinitionRegistryPostProcessor 继承自 beanfactoryPostProcessor,比 beanfactoryPostProcessor 具有更高的优先级,主要用来在常规的 beanfactoryPostProcessor 检测开始之前注册其他 bean 定义。特别是,你可以通过 BeanDeFinitionRegistryPostProcessor 来注册一些常规的 beanfactoryPostProcessor,因为此时所有常规的 beanfactoryPostProcessor 都还没开始被处理。
注意点:通过BeanDeFinitionRegistryPostProcessor 注册的 BeanDeFinitionRegistryPostProcessor 接口的postProcessBeanDeFinitionRegistry方法将得不到调用,具体的原因会在下面的代码中解释。
beanfactoryPostProcessor 接口调用机制
beanfactoryPostProcessor 接口的调用在 AbstractApplicationContext#invokebeanfactoryPostProcessors方法中。
protected void invokebeanfactoryPostProcessors(ConfigurableListablebeanfactory beanfactory) {
PostProcessorRegistrationDelegate.invokebeanfactoryPostProcessors(beanfactory,getbeanfactoryPostProcessors());
// Detect a LoadTimeweaver and prepare for weaving,if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClasspostProcessor)
if (beanfactory.getTempClassLoader() == null && beanfactory.containsBean(LOAD_TIME_weaveR_BEAN_NAME)) {
beanfactory.addBeanPostProcessor(new LoadTimeweaverAwareProcessor(beanfactory));
beanfactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanfactory.getBeanClassLoader()));
}
}
进入PostProcessorRegistrationDelegate.invokebeanfactoryPostProcessors(beanfactory,getbeanfactoryPostProcessors())方法:
public static void invokebeanfactoryPostProcessors(
ConfigurableListablebeanfactory beanfactory,List<beanfactoryPostProcessor> beanfactoryPostProcessors) {
// 用于存放已经处理过的Bean名字
Set<String> processedBeans = new HashSet<>();
// 一般会进入这个判断
if (beanfactory instanceof BeanDeFinitionRegistry) {
BeanDeFinitionRegistry registry = (BeanDeFinitionRegistry) beanfactory;
// 所谓的regularPostProcessors就是指实现beanfactoryPostProcessor接口的Bean
List<beanfactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 所谓的registryProcessors就是指实现BeanDeFinitionRegistryPostProcessor接口的Bean
List<BeanDeFinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 这边遍历的是通过ApplicationContext接口注册的beanfactoryPostProcessor和BeanDeFinitionRegistryPostProcessor接口
// 需要和beanfactory中BeanDeFinitionMap中的beanfactoryPostProcessor接口区分开
for (beanfactoryPostProcessor postProcessor : beanfactoryPostProcessors) {
if (postProcessor instanceof BeanDeFinitionRegistryPostProcessor) {
BeanDeFinitionRegistryPostProcessor registryProcessor =
(BeanDeFinitionRegistryPostProcessor) postProcessor;
//如果是BeanDeFinitionRegistryPostProcessor,则先进行postProcessBeanDeFinitionRegistry处理,这个方法一般进行BeanDeFinition注册,从这边可以看出BeanDeFinitionRegistryPostProcessor接口的方法先调用,所以优先级高于beanfactoryPostProcessor
// 通过这个代码可以看出,通过ApplicationContext直接注册的beanfactoryPostProcessor和BeanDeFinitionRegistryPostProcessor并不支持Order接口,而是根据注册的顺序执行
registryProcessor.postProcessBeanDeFinitionRegistry(registry);
// 保存这个BeanDeFinitionRegistryPostProcessor,因为还要执行这个类的beanfactoryPostProcessor方法;
registryProcessors.add(registryProcessor);
}
else {
// 保存,后面还要执行这个类的beanfactoryPostProcessor方法;
regularPostProcessors.add(postProcessor);
}
}
List<BeanDeFinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 这边获取的是beanfactory中的BeanDeFinitionRegistryPostProcessor
String[] postProcessorNames =
beanfactory.getBeanNamesForType(BeanDeFinitionRegistryPostProcessor.class,true,false);
for (String ppName : postProcessorNames) {
//先处理PriorityOrdered标注的BeanDeFinitionRegistryPostProcessor
if (beanfactory.isTypeMatch(ppName,PriorityOrdered.class)) {
currentRegistryProcessors.add(beanfactory.getBean(ppName,BeanDeFinitionRegistryPostProcessor.class));
//将其标记为已经处理,防止重复处理
processedBeans.add(ppName);
}
}
// 将其排序,以便按顺序处理
sortPostProcessors(currentRegistryProcessors,beanfactory);
// 将其保存,以便处理这个类的beanfactoryPostProcessor方法
registryProcessors.addAll(currentRegistryProcessors);
// 执行BeanDeFinitionRegistryPostProcessor接口方法
invokeBeanDeFinitionRegistryPostProcessors(currentRegistryProcessors,registry);
// 清除,以便开始处理@Order标注的注解
currentRegistryProcessors.clear();
// 注意:这边重新获取BeanDeFinitionRegistryPostProcessor是有深意的,因为上面在处理@PriorityOrdered标注的BeanDeFinitionRegistryPostProcessor时可能又注入了新的BeanDeFinitionRegistryPostProcessor。
postProcessorNames = beanfactory.getBeanNamesForType(BeanDeFinitionRegistryPostProcessor.class,false);
for (String ppName : postProcessorNames) {
// 判断是否处理过,防止重复处理,下面的逻辑和上面相同, 不介绍了
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
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanfactory.getBeanNamesForType(BeanDeFinitionRegistryPostProcessor.class,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 方法,所以BeanDeFinitionRegistryPostProcessor中的postProcessbeanfactory方法的优先级要高。
invokebeanfactoryPostProcessors(registryProcessors,beanfactory);
invokebeanfactoryPostProcessors(regularPostProcessors,beanfactory);
}
else {
// Invoke factory processors registered with the context instance.
invokebeanfactoryPostProcessors(beanfactoryPostProcessors,beanfactory);
}
// 开始处理beanfactoryPostProcessor接口
String[] postProcessorNames =
beanfactory.getBeanNamesForType(beanfactoryPostProcessor.class,false);
// 也是按照@PriorityOrdered @Ordered 和普通的方式进行处理
List<beanfactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonorderedPostProcessorNames = new ArrayList<>();
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标注的接口
sortPostProcessors(priorityOrderedPostProcessors,beanfactory);
invokebeanfactoryPostProcessors(priorityOrderedPostProcessors,beanfactory);
// 处理@Order标注的类
List<beanfactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
// 这边通过名字重新拿了Bean,应该是怕上面的处理改变了Bean
orderedPostProcessors.add(beanfactory.getBean(postProcessorName,beanfactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors,beanfactory);
invokebeanfactoryPostProcessors(orderedPostProcessors,beanfactory);
// 最后调用普通的beanfactoryPostProcessor
List<beanfactoryPostProcessor> nonorderedPostProcessors = new ArrayList<>(nonorderedPostProcessorNames.size());
for (String postProcessorName : nonorderedPostProcessorNames) {
nonorderedPostProcessors.add(beanfactory.getBean(postProcessorName,beanfactoryPostProcessor.class));
}
invokebeanfactoryPostProcessors(nonorderedPostProcessors,beanfactory);
// Clear cached merged bean deFinitions since the post-processors might have
// modified the original Metadata,e.g. replacing placeholders in values...
beanfactory.clearMetadataCache();
}
简单总结
上面的方法看起来很长很复杂,但其实干的事情并不多,就调用了beanfactoryPostProcessor和BeanDeFinitionRegistryPostProcessor接口的实现。这边再简单总结下具体的过程:
step1:执行通过ApplicationContext#addbeanfactoryPostProcessor()方法注册的beanfactoryPostProcessor和BeanDeFinitionRegistryPostProcessor。
具体过程如下:假如通过ApplicationContext注册了一个beanfactoryPostProcessor和BeanDeFinitionRegistryPostProcessor,那么会先执行BeanDeFinitionRegistryPostProcessor的postProcessBeanDeFinitionRegistry方法,但是BeanDeFinitionRegistryPostProcessor的postProcessbeanfactory方法和beanfactoryPostProcessor的postProcessbeanfactory方法暂时都不会在这步执行。
另外需要注意的是:通过ApplicationContext注册的beanfactoryPostProcessor和BeanDeFinitionRegistryPostProcessor都不支持@PriorityOrdered和@Ordered顺序处理,而是按照我们添加的顺序处理
step2:处理beanfactory中的BeanDeFinitionRegistryPostProcessor,处理的顺序是先处理@PriorityOrdered标注的,再处理@Ordered标注的,最后处理普通的BeanDeFinitionRegistryPostProcessor。到这边,所有BeanDeFinitionRegistryPostProcessor接口的postProcessBeanDeFinitionRegistry方法都已经调用完毕,下面就开始处理beanfactoryPostProcessor的postProcessbeanfactory方法。
step3:调用BeanDeFinitionRegistryPostProcessor实现的postProcessbeanfactory方法(因为BeanDeFinitionRegistryPostProcessor是beanfactoryPostProcessor的子接口)
step4:调用通过ApplicationContext#addbeanfactoryPostProcessor()注册的“单纯”的beanfactoryPostProcessor
step5:调用beanfactory中的beanfactoryPostProcessor,调用顺序也是按照@PriorityOrdered和@Ordered顺序处理,没有这两个注解的最后处理。
好了,到这边beanfactoryPostProcessor和BeanDeFinitionRegistryPostProcessor接口就已经处理完了。后面我们会拿ConfigurationClasspostProcessor 这个特殊的BeanDeFinitionRegistryPostProcessor做列子讲下具体流程,这边只是介绍beanfactoryPostProcessor的调用机制。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。