ContextLoaderListener和Spring MVC中的DispatcherServlet載入內容的區別【轉】
原文地址:https://blog.csdn.net/py_xin/article/details/52052627
ContextLoaderListener和DispatcherServlet都會在Web容器啟動的時候載入一下bean配置.
區別:
- DispatcherServlet一般會載入MVC相關的bean配置管理(如: ViewResolver, Controller, MultipartResolver, ExceptionHandler, etc.)
- ContextLoaderListener一般會載入整個Spring容器相關的bean配置管理(如: Log, Service, Dao, PropertiesLoader, DataSource Bean, etc.)
DispatcherServlet:
- DispatcherServlet預設使用WebApplicationContext作為上下文.
- DispatcherServlet也可以配置自己的初始化引數,覆蓋預設配置。
引數 | 描述 |
contextClass |
實現WebApplicationContext介面的類,當前的servlet用它來建立上下文。如果這個引數沒有指定, 預設使用XmlWebApplicationContext。 |
contextConfigLocation | 傳給上下文例項(由contextClass指定)的字串,用來指定上下文的位置。這個字串可以被分成多個字串(使用逗號作為分隔符) 來支援多個上下文(在多上下文的情況下,如果同一個bean被定義兩次,後面一個優先)。 預設為/WEB-INF/[server-name]-servlet.xml |
namespace | WebApplicationContext名稱空間。預設值是[server-name]-servlet。 |
例子如下:
<servlet> <servlet-name>demo</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-servlet-config.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>demo</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
值得注意的是, DispatcherServlet的上下文僅僅是Spring MVC的上下文, 而ContextLoaderListener的上下文則對整個Spring都有效. 一般Spring web專案中同時會使用這兩種上下文.
上下文建立完後會放在ServletContext物件中, 其中:
1) ContextLoaderListener載入的上下文放在ServletContext的key為WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性中;
2) DispatcherServlet載入的上下文在每次請求時會放一份在request物件的key為WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性中.
因而兩者的獲取方式也不一樣, 前者可以通過:
WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)或
WebApplicationContextUtils.getWebApplicationContext(servletContext)或
WebApplicationContextUtils.getWebApplicationContext(servletContext,attrname)方法來獲取對應的applicationContext,
而後者則通過:
RequestContextUtils.getWebApplicationContext(request)或
WebApplicationContextUtils.getWebApplicationContext(servletContext,attrname)方法來獲取對應的applicationContext.
(注: 對於ContextLoaderListener載入的上下文, attrname即上面提到的WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;
而對於DispatcherServlet中的上下文則為FrameworkServlet.class.getName() + ".CONTEXT." + getServletName())
通過上下文所在的屬性可以看出,如果通過WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)來試圖獲取DispatcherServlet載入的applicationContext時, 就會丟擲"No WebApplicationContext found: no ContextLoaderListener registered?"的異常.