探究Spring的后置處理器
文章目錄
- 探究Spring的后置處理器
- 流程圖
- prepareRefresh剖析
- obtainFreshBeanFactory刨析
- prepareBeanFactory刨析
- invokeBeanFactoryPostProcessors剖析
本次我們主要探究
invokeBeanFactoryPostProcessors();后面的代碼下次再做決議;
入口代碼refresh()
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// ......
applicationContext.refresh();
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 啟動前的準備作業:記錄啟動時間,活動標記為啟動以及環境屬性變數集合的初始化
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//還是一些準備作業,添加了兩個后置處理器:ApplicationContextAwareProcessor,ApplicationListenerDetector
//還設定了 忽略自動裝配 和 允許自動裝配 的介面
//對環境,系統環境,系統屬性三個Bean如果不存在某個bean的時候,spring就自動生成singleton bean(Not bd)
//還設定了bean運算式決議器 等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 空方法
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//執行自定義的BeanFactoryProcessor和內置的BeanFactoryProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
流程圖

prepareRefresh剖析
該方法主要做啟動前的準備作業:記錄啟動時間,活動標記為啟動以及環境屬性變數集合的初始化;
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// Initialize any placeholder property sources in the context environment.
// 空方法
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
obtainFreshBeanFactory刨析
主要是獲取context背景關系中的bean工廠;
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// CAS保證同步
refreshBeanFactory();
// 回傳beanFactory- DefaultListableBeanFactory.class
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
return beanFactory;
}
prepareBeanFactory刨析
做一些準備作業,添加了兩個后置處理器ApplicationContextAwareProcessor和ApplicationListenerDetector;
設定了bean運算式決議器等;
通過工廠的介面可以設定了忽略自動裝配,和允許自動裝配;
對環境、系統環境、系統屬性三個Bean如果不存在某個bean的時候,spring就自動生成singletonBean(Not bd);
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
//設定bean運算式決議器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//屬性編輯器支持
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//添加一個后置處理器:ApplicationContextAwareProcessor,此后置處理處理器實作了BeanPostProcessor介面
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//以下介面,忽略自動裝配
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
// .....
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
//以下介面,允許自動裝配,第一個引數是自動裝配的型別,,第二個欄位是自動裝配的值
// 這個介面僅會將注入的引數XXX.class注入為指定的值,但不影響XXX.class創建Bean物件;
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
// Register default environment beans.
// 環境,系統環境,系統屬性 因此通常情況下,這三個Bean是沒有bd的
//如果沒有注冊過bean名稱為XXX,spring就自己創建一個名稱為XXX的singleton bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
invokeBeanFactoryPostProcessors剖析
執行自定義的BeanFactoryProcessor和內置的BeanFactoryProcessor;
getBeanFactoryPostProcessors()方法是我們手動通過執行addBeanFactoryPostProcessor(XX)設定自定義的后置處理器,如果初始化執行到這,沒有手動增加后置處理器的話,那么此時List<BeanFactoryPostProcessor>的size()為empty;
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// getBeanFactoryPostProcessors是spring允許我們手動添加BeanFactoryPostProcessor
// 即:annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX);
// 未手動添加的話,getBeanFactoryPostProcessors()為empty
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()方法,從而去掃描并執行BeanFactoryProcessor和BeanDefinitionRegistryPostProcessor;
我們通過繼承關系看,BeanDefinitionRegistryPostProcessor實際上是繼承BeanFactoryProcessor介面的;

BeanDefinitionRegistryPostProcessor:主要掃描類決議類;BeanFactoryProcessor:主要給配置類進行增強代理;
這里面需要看我們的BeanFactory的型別;初始時BeanFactory的型別是DefaultListableBeanFactory;因此,該bean工廠是實作BeanDefinitionRegistry;

該方法的具體流程如下(按初始化進入到這里描述):
-
回圈遍歷手動添加的后置處理器(并不排序);
-
若該bfp是bdrp則直接執行
bdrp. postProcessBeanDefinitionRegistry(); -
取出內置的bdrp,分為實作了
PriorityOrdered,Ordered和都沒有實作的三類;初始這里只有一個,就是我們在初始化reader()時,注冊了一個
ConfigurationClassPostProcessor.class;
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {} -
將上面三類直接執行
bdrp. postProcessBeanDefinitionRegistry(); -
然后將手動加入和內置的bdrp執行
bfp.postProcessBeanFactory(); -
上面的已經執行完了:
- 手動添加的后置處理器的
bdrf. postProcessBeanDefinitionRegistry()和bfp.postProcessBeanFactory(); - 內置的
bdrp. postProcessBeanDefinitionRegistry()
- 手動添加的后置處理器的
-
取出內置的bfp,分為實作了
PriorityOrdered,Ordered和都沒有實作的三類;目前這里內置的有兩個,但其中config上面已經執行過了,此處只執行下方的一個;

-
將上面三類直接執行
bfp. postProcessBeanDefinitionRegistry(); -
清除快取中的bd,因為后處理器可能有修改了原始元資料,例如替換值中的占位符;
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 如果不是BeanDefinitionRegistry 則直接執行beanFactoryPostProcessors
// 剛啟動時傳入的beanFactory是DefaultListableBeanFactory,他是實作了BeanDefinitionRegistry 因此會走這里
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// bf后置處理器集合(手動添加與bdr后置處理器集合【下面的那個集合】):因為bdrp屬于bfp
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// bdr后置處理器集合(手動添加與spring自己的)
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 回圈傳進來的beanFactoryPostProcessors,剛啟動時未手動增加的情況下beanFactoryPostProcessors肯定沒有資料
// 因為beanFactoryPostProcessors是獲得手動添加的,而不是spring掃描的
// 只有手動呼叫annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)才會有資料
// 執行手動添加的beanFactoryPostProcessors, 如果是BeanDefinitionRegistryPostProcessor,則執行其postProcessBeanDefinitionRegistry再加到list中
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
//一個臨時變數,用來裝載BeanDefinitionRegistryPostProcessor為了排序
//BeanDefinitionRegistry繼承了PostProcessorBeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 獲得實作BeanDefinitionRegistryPostProcessor介面的類
// 就是ConfigurationClassPostProcessor(Spring自己添加的-在reader()時增加的)
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//獲得ConfigurationClassPostProcessor類,并且放到currentRegistryProcessors
//ConfigurationClassPostProcessor是很重要的一個類,它實作了BeanDefinitionRegistryPostProcessor介面
//BeanDefinitionRegistryPostProcessor介面又實作了BeanFactoryPostProcessor介面
//ConfigurationClassPostProcessor是極其重要的類
//里面執行了掃描Bean,Import,ImportResouce等各種操作
//用來處理配置類(有兩種情況 一種是傳統意義上的配置類,一種是普通的bean)的各種邏輯
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//把name放到processedBeans,后續會根據這個集合來判斷處理器是否已經被執行過了
processedBeans.add(ppName);
}
}
//處理排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合并Processors,為什么要合并,因為registryProcessors是裝載BeanDefinitionRegistryPostProcessor的
//一開始的時候,spring只會執行BeanDefinitionRegistryPostProcessor獨有的方法
//而不會執行BeanDefinitionRegistryPostProcessor父類的方法,即BeanFactoryProcessor的方法
//所以這里需要把處理器放入一個集合中,后續統一執行父類的方法
registryProcessors.addAll(currentRegistryProcessors);
//可以理解為執行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
//Spring熱插播的體現,像ConfigurationClassPostProcessor就相當于一個組件,Spring很多事情就是交給組件去管理
//將spring提供的RegistryProcessors(就是這個ConfigurationClassPostProcessor)執行其postProcessBeanDefinitionRegistry
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空臨時變數
currentRegistryProcessors.clear();
// 再次根據BeanDefinitionRegistryPostProcessor獲得BeanName,看這個BeanName是否已經被執行過了,有沒有實作Ordered介面
// 如果沒有被執行過,也實作了Ordered介面的話,把物件推送到currentRegistryProcessors,名稱推送到processedBeans
// 如果沒有實作Ordered介面的話,這里不把資料加到currentRegistryProcessors,processedBeans中,后續再做處理
// 這里才可以獲得我們定義的實作了BeanDefinitionRegistryPostProcessor的Bean
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, 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);
//合并Processors
registryProcessors.addAll(currentRegistryProcessors);
//執行有Ordered的BeanDefinitionRegistryPostProcessor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空臨時變數
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 下面的代碼就是執行沒有實作PriorityOrdered介面也沒有Ordered的BeanDefinitionRegistryPostProcessor
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();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//registryProcessors集合裝載BeanDefinitionRegistryPostProcessor
//上面的代碼是執行bfr后置處理器子類獨有的方法,這里需要再把bfr后置處理器父類的方法也執行一次
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//regularPostProcessors裝載BeanFactoryPostProcessor,執行BeanFactoryPostProcessor的方法
//但是regularPostProcessors一般情況下,是不會有資料的,只有在外面手動添加BeanFactoryPostProcessor,才會有資料
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
// 若bfp沒有繼承bdrp則直接執行手動增加bf后置處理器的后置處理器
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 找到BeanFactoryPostProcessor實作類的BeanName陣列
// 處理Spring自己的bf后置處理器
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// PriorityOrdered的bf后置處理器集合
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// Ordered的bf后置處理器集合
List<String> orderedPostProcessorNames = new ArrayList<>();
// 無PriorityOrdered無Ordered的bf后置處理器集合
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//回圈BeanName陣列
for (String ppName : postProcessorNames) {
//如果這個Bean被執行過了,跳過
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
//如果實作了PriorityOrdered介面,加入到priorityOrderedPostProcessors
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
//如果實作了Ordered介面,加入到orderedPostProcessorNames
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
//如果既沒有實作PriorityOrdered,也沒有實作Ordered,加入到nonOrderedPostProcessorNames
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
//排序處理priorityOrderedPostProcessors,即實作了PriorityOrdered介面的BeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//執行priorityOrderedPostProcessors
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
//執行實作了Ordered介面的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// 執行既沒有實作PriorityOrdered介面,也沒有實作Ordered介面的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
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...
// 清除了allBeanNamesByType&singletonBeanNamesByType()
// 清除快取中的bd,因為后處理器可能有修改了原始元資料,例如替換值中的占位符
beanFactory.clearMetadataCache();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/330303.html
標籤:java
上一篇:java集合中的Map集合
