spring framework 源碼分析熙参,從入口開始

本文結(jié)合上一篇編譯spring的源碼和單元測試以及spring官方文檔孽椰,從細(xì)節(jié)入手泥兰,學(xué)習(xí)spring frmaework的使用方法以及實(shí)現(xiàn)原理题禀,另一個(gè)目的:學(xué)會(huì)如何查看開源項(xiàng)目源碼


首先從spring入口開始,spring編譯好的源碼中找到/spring-webmvc/src/test/resources/org/springframework/web/context/WEB-INF/web.xml文件迈嘹,為什么先找這個(gè)文件?(Web.xml詳解 )

<!-- This servlet must be loaded first to configure the log4j system and create the WebApplicationContext -->
<servlet>
    <servlet-name>config</servlet-name>
    <servlet-class>org.springframework.framework.web.context.ContextLoaderServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.framework.web.context.XMLWebApplicationContext</param-value>       
    </init-param>
    <init-param>
        <param-name>log4jPropertiesUrl</param-name>
        <param-value>/WEB-INF/log4j_PRODUCTION.properties</param-value>     
    </init-param>
    <!-- This is essential -->
    <load-on-startup>1</load-on-startup>
  </servlet>

可以看到首先加載org.springframework.framework.web.context.ContextLoaderServlet文件,再eclipse 中Ctrl+Shift+R,搜索此文件神僵,竟然沒找到??保礼,出師不利呀.

百度“找不到ContextLoaderServlet”,提示因在Spring3.0中去掉了ContextLoaderServletLog4jConfigServlet目派,所以會(huì)出現(xiàn)找不到類的異常錯(cuò)誤胁赢。Spring3.0下可以采用另外兩種啟動(dòng)方式:ContextLoaderListenerContextLoaderPlugIn智末。建議使用ContextLoaderListener。于是查找ContextLoaderListener文件,這個(gè)總算是有送漠,不明白為什么源碼和配置文件不匹配呢它呀?然后網(wǎng)上找了一個(gè)使用ContextLoaderListener的配置web.xml 棒厘。

<!-- 項(xiàng)目中使用Spring 時(shí)奢人,applicationContext.xml配置文件中并沒有BeanFactory,要想在業(yè)務(wù)層中的class 文件中直接引用Spring容器管理的bean可通過以下方式-->  
<!--1句惯、在web.xml配置監(jiān)聽器ContextLoaderListener-->  
<!--ContextLoaderListener的作用就是啟動(dòng)Web容器時(shí)抢野,自動(dòng)裝配ApplicationContext的配置信息。因?yàn)樗鼘?shí)現(xiàn)了ServletContextListener這個(gè)接口启涯,在web.xml配置這個(gè)監(jiān)聽器,啟動(dòng)容器時(shí)恃轩,就會(huì)默認(rèn)執(zhí)行它實(shí)現(xiàn)的方法结洼。  
在ContextLoaderListener中關(guān)聯(lián)了ContextLoader這個(gè)類,所以整個(gè)加載配置過程由ContextLoader來完成叉跛。  
它的API說明  
第一段說明ContextLoader可以由 ContextLoaderListener和ContextLoaderServlet生成松忍。  
如果查看ContextLoaderServlet的API,可以看到它也關(guān)聯(lián)了ContextLoader這個(gè)類而且它實(shí)現(xiàn)了HttpServlet這個(gè)接口  
第二段筷厘,ContextLoader創(chuàng)建的是 XmlWebApplicationContext這樣一個(gè)類鸣峭,它實(shí)現(xiàn)的接口是WebApplicationContext->ConfigurableWebApplicationContext->ApplicationContext->  
BeanFactory這樣一來spring中的所有bean都由這個(gè)類來創(chuàng)建  
 IUploaddatafileManager uploadmanager = (IUploaddatafileManager)    ContextLoaderListener.getCurrentWebApplicationContext().getBean("uploadManager");
 -->  
<listener>  
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
</listener>  
<!--2、部署applicationContext的xml文件-->  
<!--如果在web.xml中不寫任何參數(shù)配置信息酥艳,默認(rèn)的路徑是"/WEB-INF/applicationContext.xml叽掘,  
在WEB-INF目錄下創(chuàng)建的xml文件的名稱必須是applicationContext.xml玖雁。  
如果是要自定義文件名可以在web.xml里加入contextConfigLocation這個(gè)context參數(shù):  
在<param-value> </param-value>里指定相應(yīng)的xml文件名更扁,如果有多個(gè)xml文件,可以寫在一起并以“,”號(hào)分隔赫冬。  
也可以這樣applicationContext-*.xml采用通配符浓镜,比如這那個(gè)目錄下有applicationContext-ibatis-base.xml,  
applicationContext-action.xml劲厌,applicationContext-ibatis-dao.xml等文件膛薛,都會(huì)一同被載入。  
在ContextLoaderListener中關(guān)聯(lián)了ContextLoader這個(gè)類补鼻,所以整個(gè)加載配置過程由ContextLoader來完成哄啄。-->  
<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>classpath:spring/applicationContext.xml</param-value>  
</context-param>  

1.如果在web.xml中不寫任何參數(shù)配置信息,默認(rèn)的路徑是"/WEB-INF/applicationContext.xml风范, 在WEB-INF目錄下創(chuàng)建的xml文件的名稱必須是applicationContext.xml
2.如果是要自定義文件名可以在web.xml里加入contextConfigLocation這個(gè)context參數(shù)
帶著問題看源碼咨跌,1. 默認(rèn)路徑如何指定?2. 自定義文件名如何實(shí)現(xiàn)的硼婿?
打開ContextLoaderListener.java 文件锌半。

  /**
    * Initialize the root web application context.
    */
   @Override
   public void contextInitialized(ServletContextEvent event) {
       initWebApplicationContext(event.getServletContext());
   }```
進(jìn)入`initWebApplicationContext `方法
![initWebApplicationContext
](http://upload-images.jianshu.io/upload_images/2783430-03bac226391c8edd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
此方法中設(shè)置自定義配置文件,如果沒指定寇漫,通過refresh()方法調(diào)用默認(rèn)路徑
1. 默認(rèn)路徑如何指定刊殉?
![determineContextClass](http://upload-images.jianshu.io/upload_images/2783430-40b26f2ecf3f98fd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
未指定contextClassName時(shí)殉摔,從defaultStrategies取默認(rèn)className
![defaultStrategies](http://upload-images.jianshu.io/upload_images/2783430-c6a76bdf1aa6ba23.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![ContexLoad.properties](http://upload-images.jianshu.io/upload_images/2783430-5d127fa0716c8980.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
wac 返回默認(rèn)的XmlWebApplicationContext實(shí)例。
![configureAndRefreshWebApplicationContext](http://upload-images.jianshu.io/upload_images/2783430-6f6ea554f3cffd60.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
查找`XmlWebApplicationContext`的`refresh()`方法,該類中未找到记焊,一直往上層父類中尋找逸月,最終`AbstractApplicationContext`中找到。
![refresh_getDefaultConfigLocations](http://upload-images.jianshu.io/upload_images/2783430-5121dfe1a51ac594.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
`refresh()` 一級(jí)級(jí)調(diào)用直到`XmlWebApplicationContext`的`getDefaultConfigLoactions()`方法
![getDefaultConfigLocations](http://upload-images.jianshu.io/upload_images/2783430-e02c18babd6f24dd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
返回默認(rèn)的配置文件地址
2. 自定義文件名如何實(shí)現(xiàn)的遍膜?
`public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";`
![configureAndRefreshWebApplicationContext](http://upload-images.jianshu.io/upload_images/2783430-6f6ea554f3cffd60.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
檢查contextConfigLocation參數(shù)是否指定彻采?如果有,wac.setConfigLocation()添加自定義配置文件捌归。
![getConfigLocations](http://upload-images.jianshu.io/upload_images/2783430-2d7f0d8462d02e4f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
如果已經(jīng)指定自定義文件了肛响,就不再使用默認(rèn)位置。之前跟到這個(gè)地方發(fā)現(xiàn)`getDefaultConfigLocation()` 返回`null`,并未返回defaultContextLoaction惜索。后來想明白是因?yàn)閣ac 是`XmlWebApplicationContext`實(shí)例特笋,也應(yīng)該調(diào)用`XmlWebApplicationContext`的`getDefaultConfigLocation()`方法,而不是此處父類方法巾兆。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末猎物,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子角塑,更是在濱河造成了極大的恐慌蔫磨,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件圃伶,死亡現(xiàn)場離奇詭異堤如,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)窒朋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門搀罢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人侥猩,你說我怎么就攤上這事榔至。” “怎么了欺劳?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵唧取,是天一觀的道長。 經(jīng)常有香客問我划提,道長枫弟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任腔剂,我火速辦了婚禮媒区,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘掸犬。我一直安慰自己袜漩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布湾碎。 她就那樣靜靜地躺著宙攻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪介褥。 梳的紋絲不亂的頭發(fā)上座掘,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音柔滔,去河邊找鬼溢陪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛睛廊,可吹牛的內(nèi)容都是我干的形真。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼超全,長吁一口氣:“原來是場噩夢啊……” “哼咆霜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嘶朱,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蛾坯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后疏遏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脉课,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年财异,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了下翎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宝当,死狀恐怖视事,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情庆揩,我是刑警寧澤俐东,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站订晌,受9級(jí)特大地震影響虏辫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锈拨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一砌庄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦娄昆、人聲如沸佩微。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哺眯。三九已至,卻和暖如春扒俯,著一層夾襖步出監(jiān)牢的瞬間奶卓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國打工撼玄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留夺姑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓掌猛,卻偏偏與公主長得像盏浙,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子留潦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容