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,其实也不影响使用。

猜你喜欢

转载自realkcn.iteye.com/blog/2236242