最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring中ContextLoaderListener監(jiān)聽詳解

 更新時(shí)間:2024年01月05日 08:59:48   作者:it_lihongmin  
這篇文章主要介紹了Spring中ContextLoaderListener監(jiān)聽詳解,SpringMVC啟動(dòng)時(shí)會(huì)啟動(dòng)WebApplicationContext類型的容器,并且會(huì)調(diào)用之前分析的refresh方法,需要的朋友可以參考下

前言

web.xml配置文件的部分,方便下面的理解:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
 
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:Resource/SpringConf.xml</param-value>
</context-param>
  
  
<servlet>
    <servlet-name>springweb</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
	<init-param>  
		<param-name>contextConfigLocation</param-name>  
		<param-value>/WEB-INF/springweb.xml</param-value>  
	</init-param>  
    <load-on-startup>1</load-on-startup>
</servlet>
 
<servlet-mapping>
    <servlet-name>springweb</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

一、SpringMVC總覽

SpringMVC啟動(dòng)時(shí)會(huì)啟動(dòng)WebApplicationContext類型的容器,并且會(huì)調(diào)用之前分析的refresh方法。

還是從原始的SpringMVC開始,啟動(dòng)方式有三種,配置文件中配置ContextLoadServlet,ContextLoaderListener、ContextLoaderPlugin。

不論哪種方式啟動(dòng)都大致相同。主要包括兩部分:

1、ContextLoaderListener監(jiān)聽

初始化Spring容器,WebApplicationContext類型,并且執(zhí)行refresh方法

2、DispatcherServlet(一個(gè)特殊的Servlet,如上面的配置web.xml中進(jìn)行配置了)

1)、DispatcherServlet像普通Servlet一樣,init中啟動(dòng)九大件為服務(wù)請(qǐng)求做準(zhǔn)備

HttpServletBean#init => DispatcherServlet#onRefresh => DispatcherServlet#initStrategies(初始化九大件)

2)、當(dāng)上面初始化完成后,則請(qǐng)求進(jìn)入后攔截轉(zhuǎn)發(fā)到DispatcherServlet

DispatcherServlet#doService=> DispatcherServlet#doDispatch(執(zhí)行MVC流程)

二、ContextLoaderListener的contextInitialized監(jiān)聽事件

當(dāng)Web容器啟動(dòng)時(shí),觸發(fā)ContextLoaderListenercontextInitialized方法:

@Override
public void contextInitialized(ServletContextEvent event) {
    initWebApplicationContext(event.getServletContext());
}
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
    // 省略部分日志和try catch代碼
    long startTime = System.currentTimeMillis();
    if (this.context == null) {
        this.context = createWebApplicationContext(servletContext);
    }
    if (this.context instanceof ConfigurableWebApplicationContext) {
        ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
        if (!cwac.isActive()) {
            // The context has not yet been refreshed -> provide services such as
            // setting the parent context, setting the application context id, etc
            if (cwac.getParent() == null) {
                // The context instance was injected without an explicit parent ->
                // determine parent for root web application context, if any.
                ApplicationContext parent = loadParentContext(servletContext);
                cwac.setParent(parent);
            }
            configureAndRefreshWebApplicationContext(cwac, servletContext);
        }
    }
    servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
    ClassLoader ccl = Thread.currentThread().getContextClassLoader();
    if (ccl == ContextLoader.class.getClassLoader()) {
        currentContext = this.context;
    } else if (ccl != null) {
        currentContextPerThread.put(ccl, this.context);
    }
    return this.context;
}

這里需要考慮容器是否其他地方已經(jīng)創(chuàng)建了,但是不論是否創(chuàng)建。整個(gè)Spring MVC啟動(dòng)過程需要經(jīng)歷幾個(gè)步驟:

1、createWebApplicationContext(創(chuàng)建Web類型的ApplicationContext)

2、configureAndRefreshWebApplicationContext(主要是refresh方法執(zhí)行)

3、將初始化的WebApplicationContext容器,用key為ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE加載到ServletContext容器中

創(chuàng)建Web類型的ApplicationContext

protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
    Class<?> contextClass = determineContextClass(sc);
    if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
        throw new ApplicationContextException("省略");
    }
    return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
}

先判斷啟動(dòng)的WebApplicationContext的類型Class,再使用反射初始化。主要是看啟動(dòng)的Class是怎么確定的。

protected Class<?> determineContextClass(ServletContext servletContext) {
    String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
    if (contextClassName != null) {
        // 省略try catch代碼
        return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
    }
    else {
        contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
        // 省略try catch代碼
        return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
    }
}

先看啟動(dòng)Web時(shí)是否有進(jìn)行配置Class,否則就在默認(rèn)的配置策略中進(jìn)行獲取。詳細(xì)可以參見:Spring中的策略模式簡(jiǎn)單實(shí)現(xiàn)與使用分析

從配置文件ContextLoader.properties中獲取到的類型為(所以如果沒有配置默認(rèn)啟動(dòng)XmlWebApplicationContext,Spring Boot不會(huì)啟動(dòng)該類型,但是SpringMVC沒有太大差異):

org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext

執(zhí)行refresh方法

不管怎么樣都回執(zhí)行configureAndRefreshWebApplicationContext方法,以啟動(dòng)Spring 容器,也就是之前一直分析refresh方法。

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, 
                                                        ServletContext sc) {
    // 設(shè)置ConfigurableWebApplicationContext的容器Id
    if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
        // The application context id is still set to its original default value
        // -> assign a more useful id based on available information
        String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
        if (idParam != null) {
            wac.setId(idParam);
        }
        else {
            // Generate default id...
            wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
                    ObjectUtils.getDisplayString(sc.getContextPath()));
        }
    }
    // 設(shè)置Web容器上下文,設(shè)置到Spring容器中
    wac.setServletContext(sc);
    String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
    // 配置location,如果配置的話,則refresh方法時(shí)會(huì)調(diào)用Resource加載,解析,初始化
    if (configLocationParam != null) {
        wac.setConfigLocation(configLocationParam);
    }
    // 設(shè)置Environment,refresh時(shí)也分析過,如果沒有則會(huì)從java.lang.System中
    // 獲取數(shù)據(jù)初始化StandardEnvironment或其子類
    ConfigurableEnvironment env = wac.getEnvironment();
    if (env instanceof ConfigurableWebEnvironment) {
        ((ConfigurableWebEnvironment) env).initPropertySources(sc, null);
    }
    // 初始化自定義的容器,如果自己配置的話(我們可以自定義實(shí)現(xiàn)ServletContextListener)
    customizeContext(sc, wac);
    // 調(diào)用refresh方法
    wac.refresh();
}

1、設(shè)置WebApplicationContext的Id

2、設(shè)置Web容器上下文,設(shè)置到Spring容器中

3、配置location(比如上面配置中的contextConfigLocation,則refresh方法時(shí)會(huì)調(diào)用Resource加載,解析,初始化)

4、初始化自定義的監(jiān)聽

5、最重要的一步,啟動(dòng)Spring容器(可以從這里開始看:SpringIoc源碼(五)- ApplicationContext(一)- 結(jié)構(gòu)梳理)

到此這篇關(guān)于Spring中ContextLoaderListener監(jiān)聽詳解的文章就介紹到這了,更多相關(guān)ContextLoaderListener監(jiān)聽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • PowerJob分布式任務(wù)調(diào)度源碼流程解讀

    PowerJob分布式任務(wù)調(diào)度源碼流程解讀

    這篇文章主要為大家介紹了PowerJob分布式任務(wù)調(diào)度源碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-02-02
  • java常用工具類 Date日期、Mail郵件工具類

    java常用工具類 Date日期、Mail郵件工具類

    這篇文章主要為大家詳細(xì)介紹了java常用工具類,包括Date日期、Mail郵件工具類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • 各系統(tǒng)下多版本JDK安裝與配置步驟

    各系統(tǒng)下多版本JDK安裝與配置步驟

    這篇文章主要介紹了各系統(tǒng)下多版本JDK安裝與配置的相關(guān)資料,包括Windows、Mac和Linux系統(tǒng)下的具體步驟,文中通過代碼將步驟介紹的非常詳細(xì),需要的朋友可以參考下
    2026-02-02
  • java時(shí)間戳與日期相互轉(zhuǎn)換工具詳解

    java時(shí)間戳與日期相互轉(zhuǎn)換工具詳解

    這篇文章主要為大家詳細(xì)介紹了java各種時(shí)間戳與日期之間相互轉(zhuǎn)換的工具,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • SpringBoot bean查詢加載順序流程詳解

    SpringBoot bean查詢加載順序流程詳解

    當(dāng)你在項(xiàng)目啟動(dòng)時(shí)需要提前做一個(gè)業(yè)務(wù)的初始化工作時(shí),或者你正在開發(fā)某個(gè)中間件需要完成自動(dòng)裝配時(shí)。你會(huì)聲明自己的Configuration類,但是可能你面對(duì)的是好幾個(gè)有互相依賴的Bean
    2023-03-03
  • FileOutputStream文件寫入類實(shí)現(xiàn)方式

    FileOutputStream文件寫入類實(shí)現(xiàn)方式

    這篇文章主要介紹了FileOutputStream文件寫入類實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2026-03-03
  • ActiveMQ中consumer的消息確認(rèn)機(jī)制詳解

    ActiveMQ中consumer的消息確認(rèn)機(jī)制詳解

    這篇文章主要介紹了ActiveMQ中consumer的消息確認(rèn)機(jī)制詳解,對(duì)于broker而言,只有接收到確認(rèn)指令,才會(huì)認(rèn)為消息被正確的接收或者處理成功了,InforSuiteMQ提供以下幾種Consumer與Broker之間的消息確認(rèn)方式,需要的朋友可以參考下
    2023-10-10
  • SpringData JPA中@OneToMany和@ManyToOne的用法詳解

    SpringData JPA中@OneToMany和@ManyToOne的用法詳解

    這篇文章主要介紹了SpringData JPA中@OneToMany和@ManyToOne的用法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringBoot 應(yīng)用程序測(cè)試實(shí)現(xiàn)方案

    SpringBoot 應(yīng)用程序測(cè)試實(shí)現(xiàn)方案

    這篇文章主要介紹了SpringBoot 應(yīng)用程序測(cè)試實(shí)現(xiàn)方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java手機(jī)號(hào)最新校驗(yàn)規(guī)則

    Java手機(jī)號(hào)最新校驗(yàn)規(guī)則

    在Java中,進(jìn)行手機(jī)號(hào)校驗(yàn)通常使用正則表達(dá)式(Regex)來匹配手機(jī)號(hào)的格式,以下是一個(gè)基于當(dāng)前(截至2024年)中國手機(jī)號(hào)規(guī)則的校驗(yàn)方法,感興趣的朋友跟隨小編一起看看吧
    2024-05-05

最新評(píng)論

射洪县| 宁安市| 海宁市| 乌鲁木齐县| 三台县| 白朗县| 木里| 吉木萨尔县| 乌兰察布市| 巢湖市| 尤溪县| 泸定县| 瑞金市| 邵东县| 禹城市| 凤阳县| 阿瓦提县| 八宿县| 内江市| 安溪县| 靖州| 芦山县| 吉林市| 舟曲县| 贵州省| 庆元县| 林西县| 潮州市| 额尔古纳市| 甘泉县| 莆田市| 申扎县| 双鸭山市| 合山市| 微博| 济宁市| 卢龙县| 宜昌市| 白玉县| 石泉县| 建湖县|