摘要:簡介本篇文章是容器源碼分析系列文章的最后一篇文章,本篇文章所分析的對象是方法,該方法用于對已完成屬性填充的做最后的初始化工作。后置處理器是拓展點(diǎn)之一,通過實(shí)現(xiàn)后置處理器接口,我們就可以插手的初始化過程。
1. 簡介
本篇文章是“Spring IOC 容器源碼分析”系列文章的最后一篇文章,本篇文章所分析的對象是 initializeBean 方法,該方法用于對已完成屬性填充的 bean 做最后的初始化工作。相較于之前幾篇文章所分析的源碼,initializeBean 的源碼相對比較簡單,大家可以愉快的閱讀。好了,其他的不多說了,我們直入主題吧。
2. 源碼分析本章我們來分析一下 initializeBean 方法的源碼。在完成分析后,還是像往常一樣,把方法的執(zhí)行流程列出來。好了,看源碼吧:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction
以上就是 initializeBean 方法的邏輯,很簡單是不是。該方法做了如下幾件事情:
檢測 bean 是否實(shí)現(xiàn)了 *Aware 類型接口,若實(shí)現(xiàn),則向 bean 中注入相應(yīng)的對象
執(zhí)行 bean 初始化前置操作
執(zhí)行初始化操作
執(zhí)行 bean 初始化后置操作
在上面的流程中,我們又發(fā)現(xiàn)了后置處理器的蹤影。如果大家閱讀過 Spring 的源碼,會(huì)發(fā)現(xiàn)后置處理器在 Spring 源碼中多次出現(xiàn)過。后置處理器是 Spring 拓展點(diǎn)之一,通過實(shí)現(xiàn)后置處理器 BeanPostProcessor 接口,我們就可以插手 bean 的初始化過程。比如大家所熟悉的 AOP 就是在后置處理 postProcessAfterInitialization 方法中向目標(biāo)對象中織如切面邏輯的。關(guān)于“前置處理”和“后置處理”相關(guān)的源碼,這里就不分析了,大家有興趣自己去看一下。接下來分析一下 invokeAwareMethods 和 invokeInitMethods 方法,如下:
private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { // 注入 beanName 字符串 ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { // 注入 ClassLoader 對象 ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } if (bean instanceof BeanFactoryAware) { // 注入 BeanFactory 對象 ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
invokeAwareMethods 方法的邏輯很簡單,一句話總結(jié):根據(jù) bean 所實(shí)現(xiàn)的 Aware 的類型,向 bean 中注入不同類型的對象。
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { // 檢測 bean 是否是 InitializingBean 類型的 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name "" + beanName + """); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged(new PrivilegedExceptionAction
invokeInitMethods 方法用于執(zhí)行初始化方法,也不復(fù)雜,就不多說了。
3. 總結(jié)本篇文章到這里差不多就分析完了,總的來說本文的內(nèi)容比較簡單,很容易看懂。正如簡介一章中所說,本篇文章是我的“Spring IOC 容器源碼分析”系列文章的最后一篇文章。寫完這本篇文章,有種如釋重負(fù)的感覺。我在5月15號寫完 Java CAS 原理分析 文章后,次日開始閱讀 Spring IOC 部分的源碼,閱讀該部分源碼花了大概兩周的時(shí)間。然后在5月30號發(fā)布了“Spring IOC 容器源碼分析”系列文章的第一篇文章 Spring IOC 容器源碼分析系列文章導(dǎo)讀。在寫完第一篇文章后,就開啟了快速更新模式,以平均2天一篇的速度進(jìn)行更新。終于在今天,也就是6月11號寫完了最后一篇。這一段時(shí)間寫文章寫的很累,經(jīng)常熬夜。主要的原因在于,在自己看懂源碼的同時(shí),通過寫文章的方式盡量保證別人也能看懂的話,這個(gè)就比較難了。比如我在閱讀源碼的時(shí)候,在源碼上面寫了一些簡單的注釋。這些注釋我可以看懂,但如果想寫成文章,則需要把注釋寫的盡量詳細(xì),必要的背景知識也要介紹一下??偟膩碚f,認(rèn)真寫一篇技術(shù)文章還是不容易的。寫文章尚如此,那寫書呢,想必更加辛苦了。我在閱讀源碼和寫文章的過程中,也參考了一些資料(相關(guān)資料在“導(dǎo)讀”一文中指明了出處,本文就不再次說明)。在這里,向這些資料的作者表示感謝!
好了,本篇文章就到這里了,感謝大家的閱讀。
本文在知識共享許可協(xié)議 4.0 下發(fā)布,轉(zhuǎn)載需在明顯位置處注明出處附錄:Spring 源碼分析文章列表 Ⅰ. IOC
作者:coolblog.xyz
本文同步發(fā)布在我的個(gè)人博客:http://www.coolblog.xyz
更新時(shí)間 | 標(biāo)題 |
---|---|
2018-05-30 | Spring IOC 容器源碼分析系列文章導(dǎo)讀 |
2018-06-01 | Spring IOC 容器源碼分析 - 獲取單例 bean |
2018-06-04 | Spring IOC 容器源碼分析 - 創(chuàng)建單例 bean 的過程 |
2018-06-06 | Spring IOC 容器源碼分析 - 創(chuàng)建原始 bean 對象 |
2018-06-08 | Spring IOC 容器源碼分析 - 循環(huán)依賴的解決辦法 |
2018-06-11 | Spring IOC 容器源碼分析 - 填充屬性到 bean 原始對象 |
2018-06-11 | Spring IOC 容器源碼分析 - 余下的初始化工作 |
更新時(shí)間 | 標(biāo)題 |
---|---|
2018-06-17 | Spring AOP 源碼分析系列文章導(dǎo)讀 |
2018-06-20 | Spring AOP 源碼分析 - 篩選合適的通知器 |
2018-06-20 | Spring AOP 源碼分析 - 創(chuàng)建代理對象 |
2018-06-22 | Spring AOP 源碼分析 - 攔截器鏈的執(zhí)行過程 |
更新時(shí)間 | 標(biāo)題 |
---|---|
2018-06-29 | Spring MVC 原理探秘 - 一個(gè)請求的旅行過程 |
2018-06-30 | Spring MVC 原理探秘 - 容器的創(chuàng)建過程 |
本作品采用知識共享署名-非商業(yè)性使用-禁止演繹 4.0 國際許可協(xié)議進(jìn)行許可。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/69741.html
摘要:本文是容器源碼分析系列文章的第一篇文章,將會(huì)著重介紹的一些使用方法和特性,為后續(xù)的源碼分析文章做鋪墊。我們可以通過這兩個(gè)別名獲取到這個(gè)實(shí)例,比如下面的測試代碼測試結(jié)果如下本小節(jié),我們來了解一下這個(gè)特性。 1. 簡介 Spring 是一個(gè)輕量級的企業(yè)級應(yīng)用開發(fā)框架,于 2004 年由 Rod Johnson 發(fā)布了 1.0 版本。經(jīng)過十幾年的迭代,現(xiàn)在的 Spring 框架已經(jīng)非常成熟了...
摘要:關(guān)于創(chuàng)建實(shí)例的過程,我將會(huì)分幾篇文章進(jìn)行分析。源碼分析創(chuàng)建實(shí)例的入口在正式分析方法前,我們先來看看方法是在哪里被調(diào)用的。時(shí),表明方法不存在,此時(shí)拋出異常。該變量用于表示是否提前暴露單例,用于解決循環(huán)依賴。 1. 簡介 在上一篇文章中,我比較詳細(xì)的分析了獲取 bean 的方法,也就是getBean(String)的實(shí)現(xiàn)邏輯。對于已實(shí)例化好的單例 bean,getBean(String) ...
摘要:在寫完容器源碼分析系列文章中的最后一篇后,沒敢懈怠,趁熱打鐵,花了天時(shí)間閱讀了方面的源碼。從今天開始,我將對部分的源碼分析系列文章進(jìn)行更新。全稱是,即面向切面的編程,是一種開發(fā)理念。在中,切面只是一個(gè)概念,并沒有一個(gè)具體的接口或類與此對應(yīng)。 1. 簡介 前一段時(shí)間,我學(xué)習(xí)了 Spring IOC 容器方面的源碼,并寫了數(shù)篇文章對此進(jìn)行講解。在寫完 Spring IOC 容器源碼分析系列...
摘要:你也會(huì)了解到構(gòu)造對象的兩種策略。構(gòu)造方法參數(shù)數(shù)量低于配置的參數(shù)數(shù)量,則忽略當(dāng)前構(gòu)造方法,并重試。通過默認(rèn)構(gòu)造方法創(chuàng)建對象看完了上面冗長的邏輯,本節(jié)來看點(diǎn)輕松的吧通過默認(rèn)構(gòu)造方法創(chuàng)建對象。 1. 簡介 本篇文章是上一篇文章(創(chuàng)建單例 bean 的過程)的延續(xù)。在上一篇文章中,我們從戰(zhàn)略層面上領(lǐng)略了doCreateBean方法的全過程。本篇文章,我們就從戰(zhàn)術(shù)的層面上,詳細(xì)分析doCreat...
摘要:實(shí)例化時(shí),發(fā)現(xiàn)又依賴于。一些緩存的介紹在進(jìn)行源碼分析前,我們先來看一組緩存的定義??墒强赐暝创a后,我們似乎仍然不知道這些源碼是如何解決循環(huán)依賴問題的。 1. 簡介 本文,我們來看一下 Spring 是如何解決循環(huán)依賴問題的。在本篇文章中,我會(huì)首先向大家介紹一下什么是循環(huán)依賴。然后,進(jìn)入源碼分析階段。為了更好的說明 Spring 解決循環(huán)依賴的辦法,我將會(huì)從獲取 bean 的方法getB...
閱讀 3229·2023-04-26 02:27
閱讀 2145·2021-11-22 14:44
閱讀 4107·2021-10-22 09:54
閱讀 3203·2021-10-14 09:43
閱讀 759·2021-09-23 11:53
閱讀 12747·2021-09-22 15:33
閱讀 2715·2019-08-30 15:54
閱讀 2691·2019-08-30 14:04