1.Spring源碼系列-ContextLoader類解析

@(spring 源碼系列)

介紹

ContextLoader類被ContextLoaderListener類調(diào)用唇礁,來初始化application context上下文。ContextLoaderListener這個(gè)類你一定見過苍苞,如果你寫過spring mvc項(xiàng)目的話。他一定出現(xiàn)在web.xml文件里

解析從程序執(zhí)行的邏輯出發(fā)狼纬,一步步來分析羹呵。這樣做有助于理清程序邏輯,對(duì)后續(xù)遇到的問題定位也有很大幫助

時(shí)序圖

調(diào)用順序

方法調(diào)用順序

  1. initWebApplicationContext
if (this.context == null) {
//創(chuàng)建web容器上下文
                this.context = createWebApplicationContext(servletContext);
            }           
  1. createWebApplicationContext
//返回WebApplicationContext接口的實(shí)現(xiàn)類疗琉。默認(rèn)返回XmlWebApplicationContext冈欢,或者返回指定的實(shí)現(xiàn)類
Class<?> contextClass = determineContextClass(sc);
  1. determineContextClass
//獲取自定義WebApplicationContext上下文實(shí)現(xiàn)類。指定實(shí)現(xiàn)類的指定方式在web.xml里通過參數(shù)contextClass指定
String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);

if (contextClassName != null) {
                return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
                }else{
                //沒有指定實(shí)現(xiàn)類盈简,默認(rèn)返回XmlWebApplicationContext實(shí)現(xiàn)類凑耻。默認(rèn)實(shí)現(xiàn)類配置在classpath下的ContextLoader.properties里
                contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
                return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
                }
                
  1. createWebApplicationContext
//利用jdk反射太示,創(chuàng)建上下文實(shí)例.實(shí)例對(duì)象中有一個(gè)唯一標(biāo)識(shí)id,這里的id生成的時(shí)機(jī)發(fā)生在類AbstractApplicationContext的成員變量private String id = ObjectUtils.identityToString(this);
return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
  1. initWebApplicationContext
//配置和刷新容器上下文香浩,包括解析xml文件类缤,加載bean,調(diào)用beanfactorypostprocessor邻吭,beanpostprocesssor
configureAndRefreshWebApplicationContext(cwac, servletContext);

//把當(dāng)前的webapplication上下文設(shè)置到servlet上下文中餐弱。這里的key是WebApplicationContext接口的全限定名
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
  1. configureAndRefreshWebApplicationContext
//設(shè)置容器的唯一標(biāo)識(shí)id
    if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
    獲取web.xml文件參數(shù)contextId配置的容器標(biāo)識(shí)id
            String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
            if (idParam != null) {
                wac.setId(idParam);
            }
            else {  
//生成默認(rèn)的的容器id=   org.springframework.web.context.WebApplicationContext:  
    wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +                     ObjectUtils.getDisplayString(sc.getContextPath()));
            }
        }
        //設(shè)置servlet上下文到容器中
wac.setServletContext(sc);
//獲取spring配置文件未知并設(shè)置到容器中
        String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
        if (configLocationParam != null) {
            wac.setConfigLocation(configLocationParam);
        }
//創(chuàng)建容器的servlet環(huán)境
ConfigurableEnvironment env = wac.getEnvironment();

//初始化容器的servlet的環(huán)境,將servletContext和servletConfig設(shè)置到容器的servlet環(huán)境中
((ConfigurableWebEnvironment) env).initPropertySources(sc, null);

//自定制容器上下文.通過ApplicationContextInitializer初始化器來實(shí)現(xiàn)定制化囱晴。
//我們可以通過web.xml配置初始化類膏蚓,多個(gè)初始化器可通過@order注解來指定初始化順序
customizeContext(sc, wac);
// 刷新容器上下文
wac.refresh();
  1. customizeContext
// 獲取上下文初始化器,初始化器可通過web.xml配置
List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> initializerClasses =
                determineContextInitializerClasses(sc);
        for (Class<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerClass : initializerClasses) {
            Class<?> initializerContextClass =
                    GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class); 
            this.contextInitializers.add(BeanUtils.instantiateClass(initializerClass));
        }
        // 根據(jù)注解@order排序初始化器
        AnnotationAwareOrderComparator.sort(this.contextInitializers);
        // 回調(diào)初始化器速缆,定制容器上下文
        for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : this.contextInitia
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末降允,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子艺糜,更是在濱河造成了極大的恐慌剧董,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件破停,死亡現(xiàn)場(chǎng)離奇詭異翅楼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)真慢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門毅臊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人黑界,你說我怎么就攤上這事管嬉。” “怎么了朗鸠?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵蚯撩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我烛占,道長(zhǎng)胎挎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任忆家,我火速辦了婚禮犹菇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘芽卿。我一直安慰自己揭芍,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布卸例。 她就那樣靜靜地躺著沼沈,像睡著了一般流酬。 火紅的嫁衣襯著肌膚如雪币厕。 梳的紋絲不亂的頭發(fā)上列另,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音旦装,去河邊找鬼页衙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛阴绢,可吹牛的內(nèi)容都是我干的店乐。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼呻袭,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼眨八!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起左电,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤廉侧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后篓足,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體段誊,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年栈拖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了连舍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涩哟,死狀恐怖索赏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贴彼,我是刑警寧澤潜腻,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站锻弓,受9級(jí)特大地震影響砾赔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜青灼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一暴心、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杂拨,春花似錦专普、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)筋粗。三九已至,卻和暖如春炸渡,著一層夾襖步出監(jiān)牢的瞬間娜亿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工蚌堵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留买决,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓吼畏,卻偏偏與公主長(zhǎng)得像督赤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子泻蚊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345