Spring****源碼分析筆記——bean
開始使用Spring框架后,它的便捷易用,強(qiáng)大,給當(dāng)年沒有使用任何框架,從頭到尾自己敲Java Web的我來說,簡直到了天堂。
但由于對(duì)不能完全自己掌控的感覺的不爽,特別是在配置一個(gè)Spring項(xiàng)目時(shí),需要各種摸索試錯(cuò)。
于是,誕生了閱讀Spring源碼,徹底對(duì)它滾瓜爛熟,有問題精準(zhǔn)定位,并熟練使用的偉大目標(biāo)。。。。。。。。
在此,列出幾個(gè)優(yōu)點(diǎn)來鼓舞自己堅(jiān)持下去,,,,,,,畢竟,它的源碼,有8000+文件。。。。。
1、從閱讀源碼的過程中,體會(huì)大神們的各種思想、技巧和編程規(guī)范。
2、對(duì)源碼和實(shí)現(xiàn)方法熟悉了以后,更好地使用。
3、一個(gè)優(yōu)秀成熟的框架,必然有優(yōu)秀先進(jìn)的技術(shù),深入學(xué)習(xí)Java。
4、看源碼的過程中可復(fù)習(xí)自己考過就忘的基礎(chǔ)知識(shí)點(diǎn)。
Spring****術(shù)語
EJB (Enterorise JavaBean) 企業(yè)級(jí)JavaBean
POJO (Plain Old Java Object) 簡單老式Java對(duì)象
DI (Dependency Injection) 依賴注入
AOP (Aspect-Oriented Programming) 面向切面編程
ORM (Object-Relational Mapping) 對(duì)象關(guān)系映射
JMS (Java Message Service) Java信息服務(wù)
MVC (Model - View - Controller) 模型-視圖-控制器
Spring基礎(chǔ)知識(shí)匯總 Java開發(fā)必看
從一個(gè)bean的初始化過程開始
Spring 框架最基礎(chǔ)來說, 是一個(gè) DI(依賴注入) 框架. 我們把我們的程序中用到的實(shí)體對(duì)象, 也就是我們常說的 bean, 放在 Spring 框架中維護(hù), 當(dāng)我們用到這些 bean 的時(shí)候, 可以在程序的任何地方來獲取.
本文通過從頭到尾跟蹤分析代碼,來查看一個(gè)bean的初始化的實(shí)現(xiàn)。

定義和注冊(cè) bean
有4種方式定義和注冊(cè)bean:
方法一:xml 中來定義 bean 標(biāo)簽
方法二:通過注解掃描, 比如 @Service 這種類.
方法三:定義 Configuration 類, 在類中提供 @Bean 的方法來定義.
方法四:使用純粹的 programmatically 的方式來定義和注冊(cè).
在代碼中獲取bean的6種方式
方法一:在初始化時(shí)保存ApplicationContext對(duì)象
方法二:通過Spring提供的utils類獲取ApplicationContext對(duì)象
方法三:繼承自抽象類ApplicationObjectSupport
方法四:繼承自抽象類WebApplicationObjectSupport
方法五:實(shí)現(xiàn)接口ApplicationContextAware
方法六:通過Spring提供的ContextLoader
本文先分析第一種方式。
在初始化時(shí)保存ApplicationContext對(duì)象

其中,userService在xml文件中的定義為:

那么~~開始吧~~~~~
ClassPathXmlApplicationContext****類:

這里為了簡化代碼,只展示了有關(guān)系的代碼,這個(gè)類的全部代碼可自己去看~~~
其中,關(guān)于super關(guān)鍵字的具體了解可點(diǎn)擊查看:java中關(guān)鍵字 super表示的真正對(duì)象
<pre style="margin-left:21.0pt;mso-para-margin-left:2.0gd;background:white">可以看到這個(gè)類繼承了AbstractXmlApplicationContext類,那么接著看下去。</pre>
AbstractXmlApplicationContext****類(抽象類):

AbstractRefreshableConfigApplicationContext****類(抽象類)

可以看到這個(gè)類繼承了AbstractRefreshableApplicationContext類,并實(shí)現(xiàn)了BeanNameAware和InitializingBean接口。
關(guān)于Java中的類和接口的不同,可點(diǎn)擊閱讀: Java 抽象類、普通類、接口的區(qū)別——值得你一看的干貨 Java抽象類與接口的區(qū)別
其中,Assert.noNullElements,是使用的Assert類的noNullElements方法,這個(gè)方法使用了@Deprecated注解,表示這個(gè)方法將被棄用,不建議使用。getEnvironment()方法在AbstractApplicationContext類中定義,會(huì)在這個(gè)類中詳細(xì)分析。
具體的Spring注解,可點(diǎn)擊查看:Spring常用注解介紹【經(jīng)典總結(jié)】

AbstractRefreshableApplicationContext****類(抽象類)

AbstractApplicationContext****類(抽象類)
終于到了主菜了,,,,1000+行的代碼,需要從頭到尾慢慢理一理。
其中@Override注解,表示該方法是偽代碼,表示重寫(當(dāng)然不寫也可以),不過寫上有如下好處:
1、可以當(dāng)注釋用,方便閱讀;
2、編譯器可以驗(yàn)證@Override下面的方法名是否是父類中所有的,如果沒有則報(bào)錯(cuò)。如果沒寫@Override,而下面的方法名又寫錯(cuò)了,這時(shí)編譯器是可以編譯通過的,因?yàn)榫幾g器以為這個(gè)方法是子類中自己增加的方法。Java中@Override的作用
{@link}與@see的簡單使用以及區(qū)別--如何寫好Java代碼注釋。
為了由繁化簡,還是根據(jù)代碼的執(zhí)行思路來吧~~~
到了AbstractApplicationContext類,終于沒有super(parent)了,改成了如下:

PathMatchingResourcePatternResolver類
PathMatchingResourcePatternResolver可以用來解析資源文件,主要是用來解析類路徑下的資源文件。當(dāng)然它也可以用來解析其它資源文件,如基于文件系統(tǒng)的本地資源文件。PathMatchingResourcePatternResolver在使用時(shí)可以直接new一個(gè)對(duì)象,new的時(shí)候可以通過使用帶ResourceLoader參數(shù)的構(gòu)造方法指定需要使用的ResourceLoader,解析好了資源后獲取資源時(shí)需要通過ResourceLoader獲取。
PathMatchingResourcePatternResolver其實(shí)也是實(shí)現(xiàn)了ResourceLoader接口的。空的構(gòu)造方法將使用DefaultResourceLoader獲取資源。大多數(shù)時(shí)候直接使用其空構(gòu)造函數(shù)即可。

在AbstractApplicationContext的setParent()方法中,instanceof 運(yùn)算符是用來在運(yùn)行時(shí)指出對(duì)象是否是特定類的一個(gè)實(shí)例。通過返回一個(gè)布爾值來指出,這個(gè)對(duì)象是否是這個(gè)特定類或者是它的子類的一個(gè)實(shí)例。
因?yàn)閜arent的值為null,所以這里不會(huì)運(yùn)行里面的代碼。
在前面,有個(gè)getEnvironment()函數(shù)的調(diào)用,在AbstractRefreshableConfigApplicationContext類中。下面,分析這個(gè)函數(shù)。
StandardEnvironment類繼承了AbstractEnvironment類,在AbstractEnvironment類中有resolveRequiredPlaceholders函數(shù):


繼續(xù)跟蹤下去:
這個(gè)函數(shù)在AbstractPropertyResolver類中定義:

Java 訪問權(quán)限控制:你真的了解 protected 關(guān)鍵字嗎?
SpringBoot環(huán)境屬性占位符解析和類型轉(zhuǎn)換
spring4.1.8擴(kuò)展實(shí)戰(zhàn)之一:自定義環(huán)境變量驗(yàn)證
未完待續(xù)。。。。。。。。。。。。。。。。。。。。。。
看Spring源碼真是一個(gè)極其漫長的過程啊。。。。。。。。。
參考資料: