【spring原始碼】七、後置處理器BeanPostProcessor
⑥registerBeanPostProcessors()
註冊(例項化)後置處理器
我們想要了解spring在什麼時候註冊自動代理,即@EnableAspectJAutoProxy等一系列執行的時機。這裡值得注意的是,@EnableAspectJAutoProxy的操作是在refresh()方法的invoke()
階段完成了bean定義資訊的注入,而還沒完成例項化。例項化是在registerBeanPostProcessor
註冊後置處理器階段完成的。
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean {
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
我們呼叫registerBeanPostProcessors()
的時候已經能從容器中拿到bean定義了,只是還是例項化。所以我們的流程是先例項化後置處理器,再例項化普通的bean,因為普通的bean要用到後置處理器。
呼叫棧:
- refresh()
- AbstractApplicationContext.registerBeanPostProcessors()
- PostProcessorRegistrationDelegate.registerBeanPostProcessors()
流程:即拿到bean定義後,通過getBean生成bean例項,然後在beanFactory中有個beanPostProcessors屬是個list,我們把bean追加到這個list裡即可,但要注意順序,bean是有優先順序的。
getBean步驟:
- 建立3個list用於儲存3種"要建立的後置處理器",把"beanPostProcessor定義資訊"按照priorityOrdered、ordered、nonOrdered分為3類,依次add到對應的list
- 3個list按序呼叫(priorityOrdered最優先呼叫完)註冊這些後置處理器,註冊方式是通過beanFactory.getBean去獲取例項
- 新建3個list用於儲存建立好的後置處理器。建立好後置處理器例項後依次add追加到對應的3個list,呼叫registerBeanPostProcessors(beanFactory, orderedPostProcessors);(另外一個)把後置處理器告訴工廠是什麼型別的。
PostProcessorRegistrationDelegate類;
//註冊bean的後置處理器來攔截bean的建立
public static void registerBeanPostProcessors(//前面是註冊定義,這裡是註冊
ConfigurableListableBeanFactory beanFactory,//DefaultListableBeanFactory@3daa422a
AbstractApplicationContext applicationContext)//AnnotationConfigApplicationContext@38bc8ab5
{
// 拿到指定型別的bean(後置處理器)的名字 // postProcessorNames={internalAutowiredAnnotationProcessor、internalRequiredAnnotationProcessor、internalCommonAnnotationProcessor、internalAutoProxyCreater}4個元素。只是定義還沒建立物件
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);//4個
//先獲取ioc容器已經定義了的需要建立物件的所有BeanPostProcessor的名字,這些物件是我們在配置類上註解的(比如我們之前的internalAutoProxyCreator),不是我們自己的
// 3+1+4
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() //3 我們自己的
+ 1
+ postProcessorNames.length;// 4個spring自帶的後置處理器
// 給容器中加別的postProcessor //即上面的1
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {//4個
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//優先註冊實現了PriorityOrdered介面的BeanPostProcessor
// 包括3/4個:internalAutowiredAnnotationProcessor、internalRequiredAnnotationProcessor、internalCommonAnnotationProcessor
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);//只有PriorityOrdered型別的才在for裡註冊//beanFactory為DefaultListableBeanFactory
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//包括1/4個:internalAutoProxyCreater
orderedPostProcessorNames.add(ppName);//只是加在了名字的list中
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 區分後依次註冊,加入到容器中
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);//這個方法是我們之前說的new definition和註冊建立的函式
// ---------------------------------
// internalAutoProxyCreater在這裡getBean--------
// Next, register the BeanPostProcessors that implement Ordered.//再註冊實現了Ordered介面的BeanPostProcessor//我們的@Enable就實現了這個介面
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {// 1/4個
// 例項化
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);//getBean//按名字從beanFactory中得到BeanPostProcessor//如果獲取不到就建立//註冊BeanPostProcessor實際上就是建立BeanPostProcessors物件,儲存在容器中。所以我們分析如何建立AnnotationAwareAspectJAutoProxyCreator類internalAutoProxyCreator名字的。
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// ---------------------------------
// Now, register all regular BeanPostProcessors.//再註冊沒有實現優先順序介面的BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {// 0/4個
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).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
//經測試,在這裡工廠中的bean定義已經是10個了,也就是說我們bean定義資訊一直在
//((DefaultListableBeanFactory) beanFactory).alreadyCreated結果為5個,即5個internal:1個在上個階段建立的+4個本階段建立的
}
//-----------PostProcessorRegistrationDelegate-------------------------
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
//postProcessors依次為3個、1個、0個
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
//-----------AbstractBeanFactory-------------------------
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
//this為beanFactory
this.beanPostProcessors.remove(beanPostProcessor);//移除舊的
this.beanPostProcessors.add(beanPostProcessor);//重新新增新的
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
}
相關文章
- BeanPostProcessor 後置處理器Bean
- Spring Ioc原始碼分析系列--Ioc容器註冊BeanPostProcessor後置處理器以及事件訊息處理Spring原始碼Bean事件
- Spring原始碼之BeanFactoryPostProcessor(後置處理器)Spring原始碼Bean
- 【Spring】Spring後置處理器Spring
- Spring之後置處理器Spring
- 【Spring註解驅動開發】關於BeanPostProcessor後置處理器,你瞭解多少?SpringBean
- 2.3 spring5原始碼系列---內建的後置處理器PostProcess載入原始碼Spring原始碼
- Spring原始碼分析:BeanPostProcessor原理Spring原始碼Bean
- spring原始碼分析——BeanPostProcessor介面Spring原始碼Bean
- JMeter—後置處理器(十)JMeter
- snabbdom原始碼解析(七) 事件處理原始碼事件
- Spring 高階特性之二:後置處理器PostProcessor深入理解Spring
- 5.8.2 jmeter元件-後置處理器-XPath提取器JMeter元件
- Spring系列(七) Spring MVC 異常處理SpringMVC
- Spring原始碼解讀之BeanFactoryPostProcessor的處理Spring原始碼Bean
- Spring 原始碼(8)Spring BeanPostProcessor的註冊、國際化及事件釋出機制Spring原始碼Bean事件
- 第七章 事件處理器事件
- spring原始碼深度解析— IOC 之 迴圈依賴處理Spring原始碼
- 死磕Spring原始碼-MVC處理HTTP分發請求Spring原始碼MVCHTTP
- spring原始碼解析 (七) 事務底層原始碼實現Spring原始碼
- spring4.1.8擴充套件實戰之七:控制bean(BeanPostProcessor介面)Spring套件Bean
- spring事務管理原始碼分析(二)事務處理流程分析Spring原始碼
- Spring MVC原始碼(四) ----- 統一異常處理原理解析SpringMVC原始碼
- 【TCP/IP】TCP伺服器併發處理&原始碼TCP伺服器原始碼
- Jmeter 常用後置處理器之正規表示式提取器、JSON 提取器、JSON JMESPath ExtractorJMeterJSON
- Spring MVC原始碼(二) ----- DispatcherServlet 請求處理流程 面試必問SpringMVC原始碼Servlet面試
- Spring Ioc原始碼分析系列--自動注入迴圈依賴的處理Spring原始碼
- 【原始碼】Redis命令處理過程原始碼Redis
- 原始碼解析Java Attach處理流程原始碼Java
- springmvc原始碼 ---DispatcherServlet 處理請求SpringMVC原始碼Servlet
- 七、Spring Boot 錯誤處理原理 & 定製錯誤頁面Spring Boot
- 【spring原始碼】十二、監聽器Spring原始碼
- 談談Spring中的BeanPostProcessor介面SpringBean
- spring中BeanPostProcessor之三:InitDestroyAnnotationBeanPostProcessor(01)SpringBean
- Spring原始碼之七registerListeners()及釋出訂閱模式Spring原始碼模式
- Laravel Excpetions(錯誤處理) 原始碼分析Laravel原始碼
- YYImage 原始碼剖析:圖片處理技巧原始碼
- MyBatis原始碼分析之核心處理層MyBatis原始碼