javajohn

          金色年華

          Spring源碼學(xué)習(xí)

          一、???????????? 概述

          二、???????????? Spring 初始化之旅

          a)???????? Spring 初始化的時(shí)候首先要運(yùn)行的類為: org.springframework.web.context. ContextLoaderListener org.springframework.web.context. ContextLoaderServlet

          ?????? 它們在初始化函數(shù)里無一例外地實(shí)例化了 ContextLoader , 然后調(diào)用了它的函數(shù) ???? public WebApplicationContext initWebApplicationContext(ServletContext )

          ?????? 接下來看一下在這個(gè)方法里干了寫什么

          b)??????? 在他的方法體內(nèi),關(guān)鍵是“ this.context = createWebApplicationContext(servletContext, parent); ”新建了一個(gè)“ ConfigurableWebApplicationContext ”類型的對象,在這一步實(shí)例化中幾乎完成了所有的 spring 初始化工作。讀取了所有的 spring 配置文件。它的工作步驟如下所述。

          c)??????? 首先,在將“ ConfigurableWebApplicationContext ”類型的對象實(shí)例化以后(這個(gè)對象實(shí)際的類型是這個(gè)包內(nèi)的 XmlWebApplicationContext ),然后又給這個(gè)實(shí)例設(shè)置了三個(gè)屬性,“ wac.setParent(parent); ”在默認(rèn)的初始化過程中這一步設(shè)置了一個(gè) null 值,然后又設(shè)置了一個(gè)“ wac.setServletContext(servletContext); ”,將系統(tǒng)默認(rèn)的上下文設(shè)置進(jìn)來,比較重要的是下面這一段: ??????????

          ?????? if (configLocation != null) {

          ?????? // 讀取 spring 的應(yīng)用配置文件

          ?????? wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,Configurabl?????? eWebApplicationContext.CONFIG_LOCATION_DELIMITERS));

          ?????? }

          ?????? 它將我們的配置文件名放置到 wac 變量中,以待在后續(xù)的操作中使用。然后調(diào)用 ????????? wac.refresh(); ”完成主要的初始化 BeanFactory 的操作。如下。

          d)??????? 首先我們應(yīng)該看一下我們實(shí)例化的對象

          ?????? org.springframework.web.context.support.XmlWebApplicationContext 的類圖:

          xx.jpg

          ?

          e)???????? wac.refresh(); ”從類結(jié)構(gòu)里我們能找到這個(gè)方法來自它的父類: AbstractApplicationContext 在它的 refresh() 方法內(nèi)我們可以看到 spring 的復(fù)雜邏輯。

          ?????? 首先執(zhí)行了 refreshBeanFactory(); (來自 AbstractRefreshableApplicationContext )見 f),

          f)???????? refreshBeanFactory(); 這個(gè)方法由負(fù)責(zé)維護(hù)變量 beanFactory 的子類 AbstractRefreshableApplicationContext 實(shí)現(xiàn),默認(rèn)情況下這個(gè)方法直接實(shí)例化一個(gè)新的 DefaultListableBeanFactory 類型的 BeanFacorty, 然后調(diào)用一個(gè)起緩沖作用的配置函數(shù)生成一個(gè)將 beanFacroty 包裝起來的對象 beanDefinitionReader ,然后對這個(gè)對象進(jìn)行屬性配置,實(shí)際上該方法主要負(fù)責(zé)生成一個(gè)臨時(shí)的操作對象,對應(yīng)調(diào)用的函數(shù)為“ loadBeanDefinitions(beanFactory); ”該方法為初始化期間較為重要的一個(gè)。 ?????? 該方法來自其子類: AbstractRefreshableWebApplicationContext 對應(yīng)的函數(shù):

          protected void loadBeanDefinitions(DefaultListableBeanFactory) ,然后這里又調(diào)用了自己定義的 protected void loadBeanDefinitions(XmlBeanDefinitionReader) 方法。此時(shí),它就使用到了在 c) 中設(shè)置了的( wac.setConfigLocations(……)) 我們開發(fā)中密切相關(guān)的配置文件。(同時(shí)也要記住此時(shí)這個(gè)函數(shù)的參數(shù) beanDefinitionReader ,之前已經(jīng)設(shè)置了“ beanDefinitionReader.setResourceLoader(this); ”這里的 this 是我們在前面見到的 XmlWebApplicationContext (一個(gè)定義好了的上下文))。接著往下:

          ?????? reader.loadBeanDefinitions(configLocations[i]); reader 開始加載我們配置文件內(nèi)的東西了,不過真正復(fù)雜的實(shí)現(xiàn)此時(shí)才開始,我們繼續(xù)往下走,在接下來的方法內(nèi)默認(rèn)情況下會執(zhí)行:

          if (resourceLoader instanceof ResourcePatternResolver) (該判斷條件為 true , 由于從上面我們知道: beanDefinitionReader.setResourceLoader(this); this 的類型為: XmlWebApplicationContext 所以 ((ResourcePatternResolver) resourceLoader).getResources(location); 得到一個(gè) Resource[] 數(shù)組,接下來調(diào)用:

          int loadCount = loadBeanDefinitions(resources); 該函數(shù)繼續(xù)調(diào)用自己子類定義的一系列臨時(shí)接口最終執(zhí)行到 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); 在這個(gè)函數(shù)內(nèi)初始化了處理 xml 文件的一些對象并將用戶的配置文件解析為一個(gè) Document 對象。然后又執(zhí)行了一系列函數(shù)直到

          return parser.registerBeanDefinitions(this, doc, resource); 這個(gè)函數(shù)來自我們新建的 DefaultXmlBeanDefinitionParser ,在這個(gè)類里最終執(zhí)行了對 xml 文件的解析工作和對 beanFacroty 變量執(zhí)行了設(shè)置工作。

          g)??????? 終于我們從這些繁雜的邏輯中跳了出來,繼續(xù)執(zhí)行 AbstractApplicationContext.refresh() 下面的工作,后續(xù)的代碼主要仍舊是往一些常量里面設(shè)值。

          此時(shí) spring 初始化過程就結(jié)束了。

          posted on 2006-07-05 16:55 javajohn 閱讀(8371) 評論(3)  編輯  收藏 所屬分類: spring

          Feedback

          # re: Spring源碼學(xué)習(xí) 2006-07-12 12:59 gf

          sdf  回復(fù)  更多評論   

          # re: Spring源碼學(xué)習(xí) 2006-07-12 15:07 pesome

          每篇都是精品阿,很希望在openfans看到你的blog  回復(fù)  更多評論   

          # re: Spring源碼學(xué)習(xí)[未登錄] 2011-08-10 10:54 Spring

          寫的很好,抓住了關(guān)鍵。我在看Spring 核心內(nèi)幕。通篇源碼,面面俱到,反而有點(diǎn)不知所措了。筆者寫的很好,贊一個(gè)!  回復(fù)  更多評論   



          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           

          My Links

          Blog Stats

          常用鏈接

          留言簿(7)

          隨筆分類(36)

          隨筆檔案(39)

          classmate

          good blog

          企業(yè)管理網(wǎng)站

          好友

          站點(diǎn)收藏

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 福海县| 旌德县| 绥江县| 班戈县| 阜城县| 蒙城县| 襄垣县| 石首市| 霍邱县| 芦山县| 台安县| 伊春市| 海口市| 浮梁县| 凌源市| 霍州市| 酉阳| 衢州市| 扬中市| 玛多县| 峨边| 安康市| 铅山县| 莆田市| 凤庆县| 津市市| 新乡市| 穆棱市| 房产| 汝南县| 会理县| 临江市| 青神县| 高雄县| 铜鼓县| 松潘县| 永和县| 大余县| 庆云县| 祁门县| 禹城市|