当前位置: 代码迷 >> VC/MFC >> Spring MVC 4.1.x 有关知识(一)Spring MVC的配置
  详细解决方案

Spring MVC 4.1.x 有关知识(一)Spring MVC的配置

热度:203   发布时间:2016-05-02 03:53:29.0
Spring MVC 4.1.x 相关知识(一)Spring MVC的配置

?一、引言

? ? 本系列基于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的子类。

ContextLoadListener的参数有三个:?
contextClass:自定义的context类名
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:

?

?

public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {    @Override    protected WebApplicationContext createRootApplicationContext() {        return null;    }    @Override    protected WebApplicationContext createServletApplicationContext() {        XmlWebApplicationContext cxt = new XmlWebApplicationContext();        cxt.setConfigLocation("/WEB-INF/dispatcher-servlet.xml");        return cxt;    }    @Override    protected String[] getServletMappings() {        return new String[] { "*.do" };    }    @Override    protected Filter[] getServletFilters() {        return new Filter[] { new CharacterEncodingFilter() };    }}

?三、常见问题

? ? 1.从上面可以看到,ContextLoaderListener和DispatcherServlet其实是两个层面的初始化,同时使用的时候一定记得它俩的配置不能重复,否则就会造成Bean在两个Context里面重复初始化。

? ? 2.不配置ContextLoaderListener只配置DispatcherServlet是可以的,此时DispatcherServlet会有个空的root Context,其实也不影响使用。

  相关解决方案