一、引言
本系列基于Spring 4.1.5,大部分内容来至Spring MVC 4.1.x的Reference Document。本文假设你已经对Spring IOC容器有一定了解,并对Spring MVC有初步认识。本文的Servlet是Servlet 3.0规范,可能会有一些和Servlet 2.x不太一样的。
二、Spring MVC的初始化
1. ContextLoaderListener
在web 工程中只使用spring不用MVC是可行的,这个只需要在web.xml里面配置ContextLoaderListener即可。
<web-app> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> ... </web-app>
这时ContextLoaderListener会初始化一个WebApplicationContext供Spring容器使用。你也可以通过指定contextClass参数使用自己的context class,但这个类必须是ConfigurableWebApplicationContext的子类。
contextConfigLocation:指定的spring配置文件,这里可以用空格或者逗号分隔多个xml配置文件
namespace:缺省是[servlet-name]-servlet,指定了servlet的xml配置文件名。比如名为dispatcher的servlet,缺省会载入dispatcher-servlet.xml的配置文件。其实这是对 servlet的配置
2.DispatcherServlet
这个是Spring MVC的核心,只有配置了它Spring MVC才能接管相关请求并对request进行处理。这里只讨论它的配置和初始化,关于MVC部分之后再介绍。
一个dispatcher的典型配置
<web-app> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/example/*</url-pattern> </servlet-mapping> </web-app>
这个配置表明这个dispatcher处理/example/下的所有请求。它初始化时,会读取dispatcher-servlet.xml中的bean配置。
每一个DispatcherServlet都是有自己的WebApplicationContext,它继承了ContextLoadListener生成的Root WebApplicationContext。下图说明了DispatcherServlet的application context结构。
当然,你也可以把所有bean配置放到Root WebApplicationContext里面,只需要给dispatcher一个空的配置就行了
<web-app> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/root-context.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></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
3.程序配置
dispatcher也可以通过程序配置,一般做法是实现一个WebApplicationInitializer的接口,并在OnStartup方法里面进行相关的初始化
这是个例子,里面把dispatcher和CharacterEncodingFilter都通过程序来配置
public class MyWebApplicationInitializer implements WebApplicationInitializer { private static final Logger LOG = LoggerFactory.getLogger(MyWebApplicationInitializer.class); @Override public void onStartup(ServletContext servletContext) throws ServletException { DispatcherServlet dispatcher = new DispatcherServlet(); dispatcher.setContextConfigLocation(""); //没有dispatcher特定的配置文件 ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", dispatcher); registration.setLoadOnStartup(1); // 启动时载入 registration.addMapping("*.do"); // 处理*.do的请求 CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter(); encodingFilter.setEncoding("UTF-8"); encodingFilter.setForceEncoding(true); servletContext.addFilter("encodingFilter", encodingFilter) .addMappingForServletNames(EnumSet.allOf(DispatcherType.class), true, "dispatcher"); } }也可以通过扩展Spring提供的抽象类AbstractDispatcherServletInitializer: