Spring版本:
<version>5.2.1.RELEASE</version>
上一篇:11-Spring源碼解析之refresh(4)——invokeBeanFactoryPostProcessors(2)
上一篇,我們介紹完了Spring
是如何註冊BeanFactoryPostProcessors
,如何解析@Configuration
註解標註的配置類,如何將配置類中的類信息放到beanFactory.beanDefinitionMap
中。
本篇我們繼續講解refresh
方法中調用的第六個方法:registerBeanPostProcessors
-> 註冊BeanPostProcessor
。注意,這裏是註冊,註冊!而不是調用,真正的調用是在Bean
實例化階段進行的。BeanPostProcessor
是Spring提供的擴展接口。
在講解registerBeanPostProcessors
之前,我們需要先了解BeanPostProcessor
的結構,以及他的功能是什麼。
一、 BeanPostProcessor
簡介
public interface BeanPostProcessor {
// bean初始化方法調用前被調用
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// bean初始化方法調用後被調用
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
從上面可以看出,BeanPostProcessor
接口只提供了兩個方法,這兩個方法分別是在Bean
初始化前後調用。爲了更有力的說明BeanPostProcessor
執行時機,我給出以下實例。
1. BeanPostProcessor
實例
自定義後置處理器MyBeanPostProcessor
// 使用@Component將後置處理器加入到容器中
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
// 初始化之前進行處理
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("beforeInitializtion....." + beanName);
return bean;
}
// 初始化之後進行處理
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("afterInitializtion....." + beanName);
return bean;
}
}
注意:實現接口中的兩個方法的最後返回值不能返回null,如果返回null
那麼在後續初始化方法將報空指針異常或者通過getBean()
方法獲取不到bean
實例對象,因爲後置處理器從Spring
容器中取出bean
實例對象沒有再次放回Spring
容器中。
POJO
類
public class MathCalculator {
private String name;
public MathCalculator(String name) {
this.name = name;
System.out.println("pojo類的構造方法");
}
public void init() {
System.out.println("pojo類的init方法");
}
public int div(int i, int j) {
return i / j;
}
@Override
public String toString() {
return "MathCalculator{" +
"name='" + name + '\'' +
'}';
}
}
該類有一個屬性name
,一個有參構造器,爲了方便看BeanPostProcessor
的執行順序,一個init
方法,這個init
在配置類中我會將其標誌爲初始化方法,一個toStrng
,一個div
方法,這個div
方法是爲了測試AOP
,這裏暫時用不到。
配置類Config_beanPostProcessor
@ComponentScan
@Configuration
public class Config_beanPostProcessor {
@Bean(initMethod = "init")
public Pojo pojo() {
System.out.println("給容器中添加 Pojo");
return new Pojo("pojo.Name屬性");
}
}
測試類
public class beanPostProcessorTest {
@SuppressWarnings("resource")
@Test
public void test01() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config_beanPostProcessor.class);
Pojo pojo = applicationContext.getBean(Pojo.class);
System.out.println(pojo);
}
}
輸出結果
我們可以看到BeanPostProcessor
的實現類中的兩個方法在配置類和pojo
類中都有調用。我們主要看在POJO類的調用順序:
這裏還涉及另外一個問題:因爲pojo
類是由配置類通過@Bean
方式加入到Spring
容器中的,因此在做doCreateBean - > createBeanInstance
與普通的Bean
不一樣。具體有什麼不同,在後面的文章會介紹。
另外,從上面輸出結果也可以看出,BeanPostProcessor
實現類會攔截每一個Bean
的創建,並在Bean
的初始化前後調用postProcessBeforeInitialization
和postProcessAfterInitialization
方法。
回到上面的輸出結果,我們可以看出BeanPostProcessor
類的方法的調用順序如下:
2. BeanPostProcessor
的類結構
看完了BeanPostProcessor
的執行順序,下面我們看一下Spring
中 BeanPostProcessor
的類結構
Spring
中有5大類BeanPostProcessor
,每一類在加載Bean
的時候都起着十分重要的作用。這裏先不具體介紹,我們先把整體流程看完之後,在後面會具體總結每一個BeanPostProcessor
在Spring
中的調用時機。
現在已經瞭解到BeanPostProcessor
的結構以及調用順序了,我們就可以開始分析Spring
是如何將BeanPostProcessor
註冊到beanFactoy
中的了。
二、BeanPostProcessor
註冊
2.1 當前beanFactory
中的值
終於來到了正題:refresh
調用的第六個方法registerBeanPostProcessors
。那麼在看這個方法的具體實現之前,我們還是得先看看當前beanFactory
中都註冊了哪些beanDefinition
,有哪些beanPostProcessor
和已經創建了哪些Bean
。
從上圖可以看出有10個beanDefinition
,其中
beanDefinition[0] -- beanDefinition[4]
爲Spring內置的Bean
,beanDefinition[5]
爲我們自己寫的配置類,beanDefinition[6]
爲我們自己寫的實現了BeanPostProcessor
的類,beanDefinition[7]
爲我們自己寫的pojo
類,beanDefinition[8]
爲我們自己寫的切面類(爲了做AOP
),beanDefinition[9]
爲Spring
爲了實現AOP
功能爲我們創建的內置類。
接下來看看當前BeanFactory
中已經有哪些後置處理器
beanPostProcessors[0]
和beanPostProcessors[1]
爲refresh()
調用的prepareBeanFactory()
方法中通過beanFactory.addBeanPostProcessor
添加的。具體參見:9-Spring容器創建之refresh(3)——【prepareBeanFactory】與【postProcessBeanFactory】。beanPostProcessor[2]
爲refresh
調用的invokeBeanFactoryPostProcessors()
方法的時候調用beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
添加的。
繼續看當前BeanFactory
已經創建好哪些Bean
。
看完了以上3個屬性之後,我們就可以開始分析registerBeanPostProcessors
是如何實現的了!以及執行完registerBeanPostProcessors
方法後,beanFactory
中的以上三個屬性增加了些什麼。
2.2 registerBeanPostProcessors
方法
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
調用PostProcessorRegistrationDelegate
類的方法registerBeanPostProcessors
,記得在refresh
調用第五個方法invokeBeanFactoryPostProcessors
的時候嗎?也是調用了PostProcessorRegistrationDelegate
類的方法,只不過那個時候調用的是:invokeBeanFactoryPostProcessors
方法
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 根據BeanPostProcessor類型從beanFactory獲取beanName
// 從2.1中的圖知道,beanFactory的10個bean中有4個是BeanPostProcessor類型的,具體哪4個在這一節最後的圖片中給出
// 其中3個內置類已經註冊完了。
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 向beanFactory中又註冊了一個BeanPostProcessorChecker類型的BeanPostProcessor
// beanProcessorTargetCount:爲當前BeanPostProcessor總數+1(+1是剛剛又加了一個BeanPostProcessorChecker類型的BeanPostProcessor)
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 將所有的BeanPostProcessor按照優先級(PriorityOrdered、Ordered)歸類
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 內置類就正常按照doGetBean的順序進行創建
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// ---------------------------------2.2.1具體講解registerBeanPostProcessors方法
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// ---------------------------------2.2.2簡要介紹AOP的AnnotationAwareAspectJAutoProxyCreator----
// Next, register the BeanPostProcessors that implement Ordered.
// 注意,實現AOP功能的AnnotationAwareAspectJAutoProxyCreator類在這個地方被創建,
// 在這裏創建的原因:因爲他是實現了Ordered接口的BeanPostProcessor
// 這裏不詳細介紹,在AOP文章中會詳細介紹。但是在這裏給出一下AnnotationAwareAspectJAutoProxyCreator的類圖
//----------------------------------AOP在這裏創建-------------------------------------
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// 最後又重新註冊了一次ApplicationListenerDetector,我們知道在refresh-> prepareBeanFactory方法中已經註冊過一次了
// 那麼爲什麼還要再註冊一次呢?
// 主要是想要將ApplicationListenerDetector放到所有的BeanPostProcessor最後
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
在registerBeanPostProcessors
執行之前,我們看以下beanFactory
中的beanDefinition
中有哪些BeanPostProcessor
。這些BeanPostProcessor
還沒有被註冊。
從上面可以看出,registerBeanPostProcessors
方法就是將beanFactory
的postProcessor
都註冊到BeanPostProcessor
中。另外還給beanFactory
多增加了一個BeanPostProcessor
,即BeanPostProcessorChecker
。
在執行完registerBeanPostProcessors
之後,我們看一下beanFactory
中有哪些BeanPostProcessor
beanPostProcessors[0]
和beanPostProcessors[1]
爲refresh()
調用的prepareBeanFactory()
方法中通過beanFactory.addBeanPostProcessor
添加的。具體參見:9-Spring容器創建之refresh(3)——【prepareBeanFactory】與【postProcessBeanFactory】。beanPostProcessor[2]
爲refresh
調用的invokeBeanFactoryPostProcessors()
方法的時候調用beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
添加的。
以上是調用registerBeanPostProcessors
方法之前beanFactory
中存在的BeanPostProcessor
。下面我們看一下調用registerBeanPostProcessors
之後beanFactory
中存在的BeanPostProcessor
。
beanPostProcessor[3]
爲beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
添加beanPostProcessor[4]
在Ordered
接口添加beanPostProcessor[5]
在regular
處添加beanPostProcessor[6]
-beanPostProcessor[7]
在PriorityOrdered
接口添加
在執行完registerBeanPostProcessors
方法後,beanFactory
中已經創建的Bean
如下:
其中myBeanPostProcessor
爲我們自己寫的實現了BeanPostProcessor
的類。
2.2.1 registerBeanPostProcessors
方法
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
// 將每一個BeanPostProcessor添加到beanFactory的BeanPostProcessor中
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// 如果當前的beanPostProcessor是InstantiationAwareBeanPostProcessor類型,就要將beanFactory的hasInstantiationAwareBeanPostProcessors屬性設置爲true
// 這個屬性在創建Bean的時候會用到: createBean -> resolveBeforeInstantiation
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
// 將beanPostProcessor放到beanFactory的beanPostProcessors屬性中
// private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
this.beanPostProcessors.add(beanPostProcessor);
}
2.2.2 AnnotationAwareAspectJAutoProxyCreator
這裏面涉及到AOP
功能對應的AnnotationAwareAspectJAutoProxyCreator
類型的Bean
的創建,爲什麼在這裏呢?因爲實現AOP
功能AnnotationAwareAspectJAutoProxyCreator
就是一個實現了Ordered
接口的BeanPostProcessor
。這裏不詳細講解他的創建過程,在之後的AOP
文章中具體介紹。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
他的父類ProxyProcessorSupport
實現了Ordered
接口:
public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean
三、總結
registerBeanPostProcessors
的功能:- 【功能一】爲
beanFactory
直接添加BeanPostProcessorChecker
後置處理器 - 【功能二】按照順序實例化
BeanPostProcessors
並將其添加到beanFactory
的BeanPostProcessors
中 - 【功能三】將
ApplicationListenerDetector
後置處理器移到後置處理器集合的最後
- 【功能一】爲
以上我們完成了registerBeanPostProcessors
功能的分析,下一篇我們繼續分析refresh方法中的
- 第七個方法
initMessageSource
- 第八個方法
initApplicationEventMulticaster
- 第九個方法
onRefresh
- 第十個方法
registerListeners