###web.xmlweb
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext-*.xml</param-value> </context-param> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
###ContextLoaderListener的做用 ContextLoaderListener的做用是初始ApplicationContext(默認的是XmlWebApplicationContext)而後將其放在ServletContext中。spring
initWebApplicationContext方法中的下面代碼mvc
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); configureAndRefreshWebApplicationContext根據配置文件初始化bean 配置文件片斷: <param-name>contextConfigLocation</param-name> <param-value>classpath*:dispatcher-servlet.xml</param-value> 讀取配置文件源碼片斷: configLocationParam = sc.getInitParameter("contextConfigLocation"); if(configLocationParam != null) { wac.setConfigLocation(configLocationParam); }
####ServletContext做用app
每個web應用都有一個 ServletContext與之相關聯。ui
ServletContext對象在應用啓動的被建立,在應用關閉的時候被銷燬。this
ServletContext在全局範圍內有效,相似於應用中的一個全局變量。url
###DispatcherServlet的做用 spa
####HttpServletBean做用 HttpServletBean的做用主要是作一些初始化,講web.xml中配置的參數設置到Servlet中debug
//好比初始化init-param中的參數 <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:dispatcher-servlet.xml</param-value> </init-param>code
//源碼片斷 HttpServletBean.ServletConfigPropertyValues ex = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); ServletContextResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext()); bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment())); this.initBeanWrapper(bw); bw.setPropertyValues(ex, true);
####FrameworkServlet做用 FrameworkServlet的做用講Servlet和Spring容器關聯。其實也就是初始化FrameworkServlet的屬性webApplicationContext,這個屬性表明SpringMVC上下文,它有個父類上下文,既web.xml中配置的ContextLoaderListener監聽器初始化的容器上下文。
//源碼片斷 protected WebApplicationContext initWebApplicationContext() { //這個設置springMVC的父類上下文爲ContextLoaderListener初始化的容器上下文 WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); WebApplicationContext wac = null; if(this.webApplicationContext != null) { wac = this.webApplicationContext; if(wac instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext attrName = (ConfigurableWebApplicationContext)wac; if(!attrName.isActive()) { if(attrName.getParent() == null) { attrName.setParent(rootContext); } this.configureAndRefreshWebApplicationContext(attrName); } } } if(wac == null) { wac = this.findWebApplicationContext();//通常返回的都是null //具體實現,獲取DispatcherServlet的applicationContext //WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext(), attrName); } if(wac == null) { wac = this.createWebApplicationContext(rootContext); } if(!this.refreshEventReceived) { this.onRefresh(wac); } if(this.publishContext) { //attrName1=org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher String attrName1 = this.getServletContextAttributeName(); //新建立的容器上下文設置到ServletContext中 this.getServletContext().setAttribute(attrName1, wac); if(this.logger.isDebugEnabled()) { this.logger.debug("Published WebApplicationContext of servlet \'" + this.getServletName() + "\' as ServletContext attribute with name [" + attrName1 + "]"); } } return wac; }
DispatcherServlet覆寫了FrameworkServlet中的onRefresh()方法,onRefresh()方法是鉤子方法,子類能夠重寫本身特有的方法。
protected void onRefresh(ApplicationContext context) { this.initStrategies(context); }
//初始化DispatcherServlet使用的策略 protected void initStrategies(ApplicationContext context) { this.initMultipartResolver(context); this.initLocaleResolver(context); this.initThemeResolver(context); this.initHandlerMappings(context); this.initHandlerAdapters(context); this.initHandlerExceptionResolvers(context); this.initRequestToViewNameTranslator(context); this.initViewResolvers(context); this.initFlashMapManager(context); }
總結
ContextLoaderListener和DispatcherServlet均可以配置spring相關的XML,可是它們不是合併儲存的,而是父子關係,因此建議:mvc相關的spring配置由DispatcherServlet加載,而其他的JavaBean都交給ContextLoaderListener加載