日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ContextLoaderListener介绍

發布時間:2023/12/19 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ContextLoaderListener介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在給新同事培訓Spring MVC時,有人問:可以不配置ContextLoaderListener嗎

所謂ContextLoaderListener,就是在web部署描述符即web.xml里面經常配置的一個監聽器,如下

[html]?view plain?copy
  • <listener>??
  • ????<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>??
  • </listener>??

  • 那么配合它一起使用的,經常是context-param,用來指定Spring要加載的配置文件,比如

    [html]?view plain?copy
  • <context-param>??
  • ????<param-name>contextConfigLocation</param-name>??
  • ????<param-value>/WEB-INF/teach-servlet.xml</param-value>??
  • </context-param>??
  • ??
  • <!--?Spring?MVC?-->??
  • <servlet>??
  • ????<servlet-name>teach</servlet-name>??
  • ????<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>??
  • ????<load-on-startup>1</load-on-startup>??
  • </servlet>??
  • <servlet-mapping>??
  • ????<servlet-name>teach</servlet-name>??
  • ????<url-pattern>*.action</url-pattern>??
  • </servlet-mapping>??

  • 上面兩段就是在使用Spring MVC時,常用的配置,DispatcherServlet作為Spring MVC控制器的核心調度器

    至于 teach-servlet.xml 就是配置一些Spring MVC需要使用的視圖解析器等等


    那么問題是:listener節點可以不配置嗎?答案是肯定的:可以不做任何配置!

    查看了ContextLoaderListener源代碼,發現它繼承自ContextLoader,并且實現ServletContextListener接口

    肯定得實現這個接口了,不然怎么作為Servlet的監聽器呢。。。

    ContextLoaderListener 源代碼很簡單,核心是實現了 ServletContextListener 的contextInitialized和contextDestroyed方法

    我們看下類圖結構,只列出一部分屬性和方法


    因為 contextInitialized和contextDestroyed 方法分別調用了 ContextLoader里面的initWebApplicationContext和closeWebApplicationContext方法

    所以核心最終還是 ContextLoader 實現了這個監聽器,那這個監聽器實現了什么功能呢,我們發現有兩個重要屬性

    contextConfigLocation:即在web.xml里面指定的配置文件所在目錄,如果不指定,Spring 會加載WEB_INF目錄下,符合 *Context.xml 或 spring*.xml 規則的文件

    currentContextPerThread:保存了當前WebApplicationContext


    其實監聽器的加載過程可以描述為:

    先判WebApplicationContext是否已存在,不存在的話則初始化一個XmlWebApplicationContext(WebApplicationContext的子類),并把該實例put到 currentContextPerThread 中。而初始化 XmlWebApplicationContext 時,就跟我們使用 new ClassPathXmlApplicationContext(contextConfigLocation)一樣

    將我們配置的各種bean都添加到XmlWebApplicationContext中,所以我們知道?ApplicationContext 提供各種 getBean的方法。。。

    并且可以發現 ContextLoader還提供了獲取當前 WebApplicationContext的靜態方法:之所以能獲取,是因為initWebApplicationContext初始化方法把創建的XmlWebApplicationContext 塞到了 currentContextPerThread 中


    說了一堆,跟Spring MVC 不配置ContextLoaderListener有什么關系呢。。。

    因為 ContextLoaderListener 本質上是創建了一個 WebApplicationContext ,所以你的項目里面,如果不使用 WebApplicationContext 就可以不配置該節點。

    那么只要做這種配置也是可以的:

    [html]?view plain?copy
  • <!--?Spring?MVC?-->??
  • ????<servlet>??
  • ????????<servlet-name>teach</servlet-name>??
  • ????????<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>??
  • ????????<init-param>??
  • ????????????<param-name>contextConfigLocation</param-name>??
  • ????????????<param-value>/WEB-INF/teach-servlet.xml</param-value>??
  • ????????</init-param>??
  • ????????<load-on-startup>1</load-on-startup>??
  • ????</servlet>??
  • ????<servlet-mapping>??
  • ????????<servlet-name>teach</servlet-name>??
  • ????????<url-pattern>*.action</url-pattern>??
  • ????</servlet-mapping>??

  • 發現Spring MVC 所需的配置文件不使用context-param節點指定,直接在DispatcherServlet里面配置即可

    注意:這種情況下,你的應用程序是無法使用WebApplicationContext的


    正常情況下,都會配置ContextLoaderListener,因為我們知道Spring IOC的兩種實現

    基礎的就是BeanFactory,高級的就是ApplicationContext,除非在資源非常有限的情況下,才使用BeanFactory

    否則都使用ApplicationContext,而WebApplicationContext就是其中的一種高級實現,它能提供很多有用的方法


    那么在應用程序如何獲取 WebApplicationContext 呢,有多種方式,最簡單的就是

    [java]?view plain?copy
  • WebApplicationContext?wac?=?ContextLoader.getCurrentWebApplicationContext();??

  • 這個很熟悉了吧,剛才提到了,當前應用的WebApplicationContext就保存在 ContextLoader的currentContextPerThread屬性當中


    還有基于ServletContext上下文獲取的方式

    [java]?view plain?copy
  • ServletContext?sc?=?request.getSession().getServletContext();??
  • ApplicationContext?ac1?=?WebApplicationContextUtils.getRequiredWebApplicationContext(sc);??
  • ApplicationContext?ac2?=?WebApplicationContextUtils.getWebApplicationContext(sc);??
  • WebApplicationContext?wac1?=?(WebApplicationContext)?sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);??

  • 還有一些更合適的,基于Spring提供的抽象類或者接口,在初始化Bean時注入ApplicationContext

    繼承自抽象類ApplicationObjectSupport
    說明:抽象類ApplicationObjectSupport提供getApplicationContext()方法,可以方便的獲取到ApplicationContext。
    Spring初始化時,會通過該抽象類的setApplicationContext(ApplicationContext context)方法將ApplicationContext 對象注入。

    繼承自抽象類WebApplicationObjectSupport
    說明:類似上面方法,調用getWebApplicationContext()獲取WebApplicationContext

    實現接口ApplicationContextAware
    說明:實現該接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 對象。
    Spring初始化時,會通過該方法將ApplicationContext對象注入。

    總結

    以上是生活随笔為你收集整理的ContextLoaderListener介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。