在 Servlet 3.0+ 环境中,你可以选择以编程方式配置 Servlet 容器,作为一种替代方法,或者与 web.xml 文件相结合。下面的例子注册了一个 DispatcherServlet:
import org.springframework.web.WebApplicationInitializer;
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
XmlWebApplicationContext appContext = new XmlWebApplicationContext();
appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(appContext));
registration.setLoadOnStartup(1);
registration.addMapping("/");
}
}
WebApplicationInitializer 是 Spring MVC 提供的一个接口,它可以确保你的实现被检测到并自动用于初始化任何 Servlet 3 容器。WebApplicationInitializer 的一个抽象基类实现名为 AbstractDispatcherServletInitializer,通过覆盖指定 Servlet 映射和 DispatcherServlet 配置位置的方法,使注册 DispatcherServlet 更加容易。
建议使用基于 Java 的 Spring 配置的应用程序使用这种方法,如下面的例子所示:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { MyWebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
如果你使用基于 XML 的 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/spring/dispatcher-config.xml");
return cxt;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
AbstractDispatcherServletInitializer 还提供了一种方便的方法来添加 Filter 实例,并让它们自动映射到 DispatcherServlet,正如下面的例子所示:
public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {
// ...
@Override
protected Filter[] getServletFilters() {
return new Filter[] {
new HiddenHttpMethodFilter(), new CharacterEncodingFilter() };
}
}
每个过滤器都被添加了一个基于其具体类型的默认名称,并自动映射到 DispatcherServlet 上。
AbstractDispatcherServletInitializer 的 isAsyncSupported 保护方法提供了一个单一的地方来启用对 DispatcherServlet 和所有映射到它的过滤器的异步支持。默认情况下,这个标志被设置为 true。
最后,如果你需要进一步定制 DispatcherServlet 本身,你可以重写 createDispatcherServlet 方法。