标签:
web.xml
<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的作用是初始ApplicationContext(默认的是XmlWebApplicationContext)然后将其放在ServletContext中
initWebApplicationContext方法中的下面代码 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); } refresh方法初始化bean
ServletContext :
每一个web应用都有一个 ServletContext与之相关联。 ServletContext对象在应用启动的被创建,在应用关闭的时候被销毁。 ServletContext在全局范围内有效,类似于应用中的一个全局变量。
DispatcherServlet的作用,首先看一下它的类图
HttpServletBean的作用主要是做一些初始化,讲web.xml中配置的参数设置到Servlet中
//比如初始化init-param中的参数 <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:dispatcher-servlet.xml</param-value> </init-param> //源码片段 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的作用讲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方法
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加载
标签:
原文地址:http://my.oschina.net/u/2361475/blog/504502