概述
本方法(invokeBeanFactoryPostProcessors)
會例項化和呼叫所有 BeanFactoryPostProcessor
(包括其子類BeanDefinitionRegistryPostProcessor
)。
BeanFactoryPostProcessor
介面是 Spring
初始化 BeanFactory
時對外暴露的擴充套件點,Spring
IoC 容器允許 BeanFactoryPostProcessor
在容器例項化任何 bean
之前讀取 bean
的定義,並可以修改它。
BeanDefinitionRegistryPostProcessor
繼承自 BeanFactoryPostProcessor
,比 BeanFactoryPostProcessor
具有更高的優先順序,主要用來在常規的 BeanFactoryPostProcessor
檢測開始之前註冊其他 bean
定義。特別是,你可以通過 BeanDefinitionRegistryPostProcessor
來註冊一些常規的 BeanFactoryPostProcessor
,因為此時所有常規的 BeanFactoryPostProcessor
都還沒開始被處理。
專案中的實戰
BeanDefinitionRegistryPostProcessor
初始化Bean
的例子
// 想根據配置檔案來動態的生成我們的Bean物件
public class MultiOssScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {
@Setter
private MultiOssProperties multiOssProperties;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
String beanSuffixName = StringUtils.capitalize(OssConstants.BEAN_SUFFIX_NAME);
multiOssProperties.getClients().forEach((productCode, ossProperties) -> {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(OssClient.class,
() -> OssClientUtils.buildOssClient(ossProperties))
.getRawBeanDefinition();
beanDefinition.setInitMethodName("init");
beanDefinition.setDestroyMethodName("shutDown");
beanDefinitionRegistry.registerBeanDefinition(productCode + beanSuffixName, beanDefinition);
});
}
}
複製程式碼
BeanFactoryPostProcessor初始化的時候do something
public class KeplerBeanFactoryPostInitializer implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
Map<String, AviatorFunction> aviatorFunctionMap = beanFactory.getBeansOfType(AviatorFunction.class);
if (aviatorFunctionMap.size() > 0) {
log.info("初始化自定義RuleLoader...");
aviatorFunctionMap.forEach((k, v) -> {
log.info("載入Rule:{}", k);
AviatorEvaluator.addFunction(v);
});
}
RuleLoader.initRule();
}
}
複製程式碼
跟進原始碼
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()));
}
}
複製程式碼
getBeanFactoryPostProcessors
/**
* Return the list of BeanFactoryPostProcessors that will get applied
* to the internal BeanFactory.
*/
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
複製程式碼
這邊 getBeanFactoryPostProcessors()
會拿到當前應用上下文中已經註冊的 BeanFactoryPostProcessor
,在預設情況下,this.beanFactoryPostProcessors
是返回空的。
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {
/**
* Initialize the given application context.
* @param applicationContext the application to configure
*/
void initialize(C applicationContext);
}
複製程式碼
invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
// 1.判斷beanFactory是否為BeanDefinitionRegistry,beanFactory為DefaultListableBeanFactory,
// 而DefaultListableBeanFactory實現了BeanDefinitionRegistry介面,因此這邊為true
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 用於存放普通的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
// 用於存放BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
// 2.首先處理入參中的beanFactoryPostProcessors
// 遍歷所有的beanFactoryPostProcessors, 將BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor區分開
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
// 2.1 如果是BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 2.1.1 直接執行BeanDefinitionRegistryPostProcessor介面的postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 2.1.2 新增到registryProcessors(用於最後執行postProcessBeanFactory方法)
registryProcessors.add(registryProcessor);
} else {
// 2.2 否則,只是普通的BeanFactoryPostProcessor
// 2.2.1 新增到regularPostProcessors(用於最後執行postProcessBeanFactory方法)
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 用於儲存本次要執行的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 3.呼叫所有實現PriorityOrdered介面的BeanDefinitionRegistryPostProcessor實現類
// 3.1 找出所有實現BeanDefinitionRegistryPostProcessor介面的Bean的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 3.2 遍歷postProcessorNames
for (String ppName : postProcessorNames) {
// 3.3 校驗是否實現了PriorityOrdered介面
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 3.4 獲取ppName對應的bean例項, 新增到currentRegistryProcessors中,
// beanFactory.getBean: 這邊getBean方法會觸發建立ppName對應的bean物件, 目前暫不深入解析
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 3.5 將要被執行的加入processedBeans,避免後續重複執行
processedBeans.add(ppName);
}
}
// 3.6 進行排序(根據是否實現PriorityOrdered、Ordered介面和order值來排序)
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 3.7 新增到registryProcessors(用於最後執行postProcessBeanFactory方法)
registryProcessors.addAll(currentRegistryProcessors);
// 3.8 遍歷currentRegistryProcessors, 執行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 3.9 執行完畢後, 清空currentRegistryProcessors
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 4.呼叫所有實現了Ordered介面的BeanDefinitionRegistryPostProcessor實現類(過程跟上面的步驟3基本一樣)
// 4.1 找出所有實現BeanDefinitionRegistryPostProcessor介面的類, 這邊重複查詢是因為執行完上面的BeanDefinitionRegistryPostProcessor,
// 可能會新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查詢
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 校驗是否實現了Ordered介面,並且還未執行過
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);
// 4.2 遍歷currentRegistryProcessors, 執行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 5.最後, 呼叫所有剩下的BeanDefinitionRegistryPostProcessors
boolean reiterate = true;
while (reiterate) {
reiterate = false;
// 5.1 找出所有實現BeanDefinitionRegistryPostProcessor介面的類
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 5.2 跳過已經執行過的
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
// 5.3 如果有BeanDefinitionRegistryPostProcessor被執行, 則有可能會產生新的BeanDefinitionRegistryPostProcessor,
// 因此這邊將reiterate賦值為true, 代表需要再迴圈查詢一次
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 5.4 遍歷currentRegistryProcessors, 執行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 6.呼叫所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(BeanDefinitionRegistryPostProcessor繼承自BeanFactoryPostProcessor)
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 7.最後, 呼叫入參beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 到這裡 , 入參beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已經全部處理完畢,
// 下面開始處理容器中的所有BeanFactoryPostProcessor
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 8.找出所有實現BeanFactoryPostProcessor介面的類
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 用於存放實現了PriorityOrdered介面的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
// 用於存放實現了Ordered介面的BeanFactoryPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<String>();
// 用於存放普通BeanFactoryPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
// 8.1 遍歷postProcessorNames, 將BeanFactoryPostProcessor按實現PriorityOrdered、實現Ordered介面、普通三種區分開
for (String ppName : postProcessorNames) {
// 8.2 跳過已經執行過的
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 8.3 新增實現了PriorityOrdered介面的BeanFactoryPostProcessor
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 8.4 新增實現了Ordered介面的BeanFactoryPostProcessor的beanName
orderedPostProcessorNames.add(ppName);
} else {
// 8.5 新增剩下的普通BeanFactoryPostProcessor的beanName
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// 9.呼叫所有實現PriorityOrdered介面的BeanFactoryPostProcessor
// 9.1 對priorityOrderedPostProcessors排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 9.2 遍歷priorityOrderedPostProcessors, 執行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// 10.呼叫所有實現Ordered介面的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
// 10.1 獲取postProcessorName對應的bean例項, 新增到orderedPostProcessors, 準備執行
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 10.2 對orderedPostProcessors排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 10.3 遍歷orderedPostProcessors, 執行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// 11.呼叫所有剩下的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
// 11.1 獲取postProcessorName對應的bean例項, 新增到nonOrderedPostProcessors, 準備執行
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 11.2 遍歷nonOrderedPostProcessors, 執行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
// 12.清除後設資料快取(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
// 因為後處理器可能已經修改了原始後設資料,例如, 替換值中的佔位符...
beanFactory.clearMetadataCache();
}
複製程式碼
sortPostProcessors
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) {
// 1.獲取設定的比較器
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) {
// 2.如果沒有設定比較器, 則使用預設的OrderComparator
comparatorToUse = OrderComparator.INSTANCE;
}
// 3.使用比較器對postProcessors進行排序
Collections.sort(postProcessors, comparatorToUse);
}
複製程式碼
預設情況下,比較器為 OrderComparator
;如果配置了 annotation-config
,並且值為true
,使用的是 AnnotationAwareOrderComparator
,AnnotationAwareOrderComparator
繼承自 OrderComparator
,只是重寫了部分方法,比較器的部分程式碼如下:
@Override
public int compare(Object o1, Object o2) {
return doCompare(o1, o2, null);
}
private int doCompare(Object o1, Object o2, OrderSourceProvider sourceProvider) {
// 判斷o1是否實現了PriorityOrdered介面
boolean p1 = (o1 instanceof PriorityOrdered);
// 判斷o2是否實現了PriorityOrdered介面
boolean p2 = (o2 instanceof PriorityOrdered);
// 1.如果o1實現了PriorityOrdered介面, 而o2沒有, 則o1排前面
if (p1 && !p2) {
return -1;
}
// 2.如果o2實現了PriorityOrdered介面, 而o1沒有, 則o2排前面
else if (p2 && !p1) {
return 1;
}
// 3.如果o1和o2都實現(都沒實現)PriorityOrdered介面
// Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation.
// 拿到o1的order值, 如果沒實現Ordered介面, 值為Ordered.LOWEST_PRECEDENCE
int i1 = getOrder(o1, sourceProvider);
// 拿到o2的order值, 如果沒實現Ordered介面, 值為Ordered.LOWEST_PRECEDENCE
int i2 = getOrder(o2, sourceProvider);
// 4.通過order值(order值越小, 優先順序越高)排序
return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}
複製程式碼
總結
第一點:整個 invokeBeanFactoryPostProcessors
方法圍繞兩個介面,BeanDefinitionRegistryPostProcessor
和 BeanFactoryPostProcessor
,其中 BeanDefinitionRegistryPostProcessor
繼承了 BeanFactoryPostProcessor
。BeanDefinitionRegistryPostProcessor
主要用來在常規 BeanFactoryPostProcessor
檢測開始之前註冊其他 Bean 定義,說的簡單點,就是 BeanDefinitionRegistryPostProcessor
具有更高的優先順序,執行順序在 BeanFactoryPostProcessor
之前。
第二點:整個 invokeBeanFactoryPostProcessors
方法操作了 3 種 bean 物件:
- 入參
beanFactoryPostProcessors
:拿的是AbstractApplicationContext
類的beanFactoryPostProcessors
屬性值,也就是在之前已經新增到beanFactoryPostProcessors
中的BeanFactoryPostProcessor
BeanDefinitionRegistryPostProcessor
介面實現類:實現了BeanDefinitionRegistryPostProcessor
介面,並且註冊到Spring IoC
容器中。- 常規
BeanFactoryPostProcessor
介面實現類:實現了BeanFactoryPostProcessor
介面,並且註冊到Spring IoC
容器中。
第三點:操作3種 bean 物件具體指的是呼叫它們重寫的方法,呼叫實現方法時會遵循以下的優先順序:
兩個用於排序的重要介面:PriorityOrdered
和 Ordered
,其中 PriorityOrdered
繼承了 Ordered
,並且 PriorityOrdered
的優先順序要高於 Ordered
,這跟 BeanDefinitionRegistryPostProcessor
繼承 BeanFactoryPostProcessor
有點類似。實現 Ordered
介面需要重寫 getOrder
方法,返回一個用於排序的 order
值,order
值的範圍為 Integer.MIN_VALUE ~ Integer.MAX_VALUE
,order
值越小優先順序越高,Integer.MIN_VALUE
擁有最高優先順序,而 Integer.MAX_VALUE
則對應的擁有最低優先順序。
第四點:常見的 Java EE
相關的框架或者中介軟體,經常使用 BeanFactoryPostProcessor
來進行擴充套件,例如上面的 Mybatis
,因此瞭解 BeanFactoryPostProcessor
的原理會對之後理解其他中介軟體的原理有幫助。
參考地址
如果大家喜歡我的文章,可以關注個人訂閱號。歡迎隨時留言、交流。如果想加入微信群的話一起討論的話,請加管理員簡棧文化-小助手(lastpass4u),他會拉你們進群。