web.xml中的ContextLoaderListener和DispatcherServlet区别
web.xml中的ContextLoaderListener和DispatcherServlet區別
ContextLoaderListener和DispatcherServlet都會在Web容器啟動的時候加載一下bean配置. 區別在于:
DispatcherServlet一般會加載MVC相關的bean配置管理(如: ViewResolver, Controller, MultipartResolver, ExceptionHandler, etc.)
ContextLoaderListener一般會加載整個Spring容器相關的bean配置管理(如: Log, Service, Dao, PropertiesLoader, DataSource Bean, etc.)
?
ContextLoaderListener繼承ContextLoader類,實現ServletContextListener接口(該接口監聽servlet容器的啟動和銷毀),ContextLoaderListener重寫了監聽容器啟動和銷毀的方法,在啟動時(contextInitialized),會調用initWebApplicationContext方法,進行web容器初始化。
/*** Initialize the root web application context.*/@Overridepublic void contextInitialized(ServletContextEvent event) {initWebApplicationContext(event.getServletContext());}/*** Close the root web application context.*/@Overridepublic void contextDestroyed(ServletContextEvent event) {closeWebApplicationContext(event.getServletContext());ContextCleanupListener.cleanupAttributes(event.getServletContext());}在initWebApplicationContext方法時父類contextloader內的方法(精簡):
在方法內回調用createWebApplicationContext()創建容器,該容器回根據spring內部的配置文件創建,最后強制為ConfigurableWebApplicationContext對象
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {throw new IllegalStateException("Cannot initialize context because there is already a root application context present - " +"check whether you have multiple ContextLoader* definitions in your web.xml!");}try {// Store context in local instance variable, to guarantee that// it is available on ServletContext shutdown.if (this.context == null) {this.context = createWebApplicationContext(servletContext);//ConfigurableWebApplicationContext類型對象}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, etcif (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);//真正初始化,在該方法內部有refresh()方法,在方法回調用ConfigurableWebApplicationContext父類的refresh()方法進行容器初始化//也就是AbstractApplicationContext類中的refresh()方法}}servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);return this.context;}} createWebApplicationContext(servletContext);//ConfigurableWebApplicationContext類型對象}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, etcif (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);//真正初始化,在該方法內部有refresh()方法,在方法回調用ConfigurableWebApplicationContext父類的refresh()方法進行容器初始化//也就是AbstractApplicationContext類中的refresh()方法}}servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);return this.context;}} protected WebApplicationContext createWebApplicationContext(ServletContext sc) {Class<?> contextClass = determineContextClass(sc);if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {throw new ApplicationContextException("Custom context class [" + contextClass.getName() +"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");}return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);} protected Class<?> determineContextClass(ServletContext servletContext) {String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);if (contextClassName != null) {try {return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());}catch (ClassNotFoundException ex) {throw new ApplicationContextException("Failed to load custom context class [" + contextClassName + "]", ex);}}else {contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());try {//通過反射得到一個class對象return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());}catch (ClassNotFoundException ex) {throw new ApplicationContextException("Failed to load default context class [" + contextClassName + "]", ex);}}}?
?
?DispatcherServlet本質是一個servlet,能夠攔截請求
servlet會有初始化init,同dispatcherservlet,會進行一些初始化操作:
protected void initStrategies(ApplicationContext context) { //初始化多部請求解析器,沒有默認的實現
initMultipartResolver(context); //文件上傳
//初始化地域解析器,默認實現是AcceptHeaderLocaleResolver
initLocaleResolver(context);
//初始化主題解析器,默認實現是FixedThemeResolver
initThemeResolver(context);
//初始化處理器映射,這是個集合, 默認實現是BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping
initHandlerMappings(context);
//初始化處理器適配器,這是個集合,默認實現是HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter和AnnotationMethodHandlerAdapter
initHandlerAdapters(context);
//初始化處理器異常解析器,這是個集合,默認實現是AnnotationMethodHandlerExceptionResolver,ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver
initHandlerExceptionResolvers(context);
//初始化請求到視圖名解析器,默認實現是DefaultRequestToViewNameTranslator
initRequestToViewNameTranslator(context);
//初始化視圖解析器,這是個集合,默認實現是InternalResourceViewResolver
initViewResolvers(context);? ?
}
?
posted @ 2018-06-05 14:37 犇犇丶 閱讀(...) 評論(...) 編輯 收藏總結
以上是生活随笔為你收集整理的web.xml中的ContextLoaderListener和DispatcherServlet区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: css+js杂记
- 下一篇: mybatis的插件分析