Spring mvc容器啟動

Spring web容器

Spring MVC項目啟動時會有兩個ApplicationContext容器扼脐,Root ApplicationContext用于管理Service層及以下層的bean,而dispacherServlet ApplicationContext用于管理Controller層的bean。

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
    <display-name>應用名稱</display-name>
    <!-- 用于spring容器初始化時讀取配置 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:META-INF/spring/applicationContext-*.xml</param-value>
    </context-param>
    <!-- 創(chuàng)建Spring容器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- SpringMVC前端控制器 -->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 用于spring 控制器容器配置 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/spring/webmvc-config.xml</param-value>
        </init-param>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>
                org.springframework.web.context.support.AnnotationConfigWebApplicationContext
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

解析:
web.xml中注冊了ContextLoaderListener實現(xiàn)了 ServletContextListener
ServletContextListener接口有如下方法力惯,會在servlet容器初始化和銷毀的時候回調(diào)

public interface ServletContextListener extends EventListener {
    void contextInitialized(ServletContextEvent var1);
    void contextDestroyed(ServletContextEvent var1);
}

監(jiān)聽器會在servlet容器啟動和銷毀時回調(diào)以上兩個方法放棒。
ContextLoaderListener就是在contextInitialized方法中創(chuàng)建、初始化Root ApplicationContext的站欺。

1.Root ApplicationContext容器啟動

(1)ContextLoaderListener 方式:

繼承了ContextLoader
servlet容器如tomcat啟動時回調(diào)contextInitialized()

ContextLoaderListener.contextInitialized(event)
    ContextLoader.initWebApplicationContext(event.getServletContext());
        ContextLoader.createWebApplicationContext(sc)// 從web.xml中獲取contextClass參數(shù)(上文的AnnotationConfigWebApplicationContext)姨夹,找到相應類,實例化,并設(shè)置其ServletContext

由此創(chuàng)建了 Root WebApplicationContext矾策。

(2)WebApplicationInitializer方式:

實現(xiàn)WebApplicationInitializer

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletCxt) {

        // 創(chuàng)建AC并加載配置
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();//abstractRefrshAC 創(chuàng)建BeanFactory并創(chuàng)建Bean和裝配

        // 創(chuàng)建 DispatcherServlet 并注冊
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/app/*");
        // Servlet容器啟動的時候會初始化DispatcherServlet.init會啟動子AC
    }
}

啟動流程:
StandardContext是tomcat的容器組件磷账,是servlet容器,在tomcat啟動時會頂級容器Server會掌管子容器的生命周期贾虽,層層啟動逃糟,Servlet 3.0規(guī)范在StandardContext.startInternal()時會查找啟動Spring相關(guān)的,如下調(diào)用關(guān)系:

StandardContext.startInternal()
    // servlet 3.0容器 容器啟動時會查找ServletContainerInitializer這個接口的實現(xiàn)類啟動
    SpringServletContainerInitializeron.Startup()
    // 實現(xiàn)ServletContainerInitializer蓬豁,會查找WebApplicationInitializer實現(xiàn)類
        XXWebApplicationInitializer.Startup()

2.DispatcherServlet實例化+初始化

DispatcherServlet由tomcat時啟動容器管理其生命周期調(diào)用init()方法初始化
繼承FrameworkServlet,FrameworkServlet繼承ServletBean

DispatcherServlet.init() //繼承自祖父HttpServletBean
    FrameworkServlet.initServletBean()
    FrameworkServlet.initWebApplicationContext()
        FrameworkServlet.createWebApplicationContext()//創(chuàng)建AC并設(shè)置parent
            FrameworkServlet.configureAndRefreshWebApplicationContext()
                wac.refresh();
        DispatcherServlet.onRefresh(webac)
            DispatcherServlet.initMultipartResolver(context);
            DispatcherServlet.initLocaleResolver(context);
            DispatcherServlet.initThemeResolver(context);
            DispatcherServlet.initHandlerMappings(context);
            DispatcherServlet.initHandlerAdapters(context);
            DispatcherServlet.initHandlerExceptionResolvers(context);
            DispatcherServlet.initRequestToViewNameTranslator(context);
            DispatcherServlet.initViewResolvers(context);
            DispatcherServlet.initFlashMapManager(context);

如此創(chuàng)建好了

4.為什么要有兩個ApplicationContext

(1)隔離 由于管理Controller層的子AC可以委托雙親 ApplicationContext去查找bean绰咽,所以Root ApplicationContext容器中的Bean是共享的,而子AC中的Bean卻不能被管理下層Service層和DAO層的Root Application獲取地粪,從而達到上層依賴下層的純粹性取募。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蟆技,隨后出現(xiàn)的幾起案子玩敏,更是在濱河造成了極大的恐慌,老刑警劉巖质礼,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旺聚,死亡現(xiàn)場離奇詭異,居然都是意外死亡几苍,警方通過查閱死者的電腦和手機翻屈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妻坝,“玉大人伸眶,你說我怎么就攤上這事」粝埽” “怎么了厘贼?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長圣拄。 經(jīng)常有香客問我嘴秸,道長,這世上最難降的妖魔是什么庇谆? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任岳掐,我火速辦了婚禮,結(jié)果婚禮上饭耳,老公的妹妹穿的比我還像新娘串述。我一直安慰自己,他們只是感情好寞肖,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布纲酗。 她就那樣靜靜地躺著衰腌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪觅赊。 梳的紋絲不亂的頭發(fā)上右蕊,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機與錄音吮螺,去河邊找鬼饶囚。 笑死,一個胖子當著我的面吹牛鸠补,可吹牛的內(nèi)容都是我干的坯约。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼莫鸭,長吁一口氣:“原來是場噩夢啊……” “哼闹丐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起被因,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤卿拴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后梨与,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堕花,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年粥鞋,在試婚紗的時候發(fā)現(xiàn)自己被綠了缘挽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡呻粹,死狀恐怖壕曼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情等浊,我是刑警寧澤腮郊,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站筹燕,受9級特大地震影響轧飞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜撒踪,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一过咬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧制妄,春花似錦掸绞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至砸脊,卻和暖如春具篇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凌埂。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工驱显, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瞳抓。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓埃疫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親孩哑。 傳聞我的和親對象是個殘疾皇子栓霜,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

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