21.15 基于代码的Servlet容器初始化

在Servlet 3.0以上的环境下,你可以通过编程的方式来配置Servlet容器了。你可以完全放弃web.xml,也可以两种配置方式同时使用。以下是一个注册DispatcherServlet的例子:

  1. import org.springframework.web.WebApplicationInitializer;
  2. public class MyWebApplicationInitializer implements WebApplicationInitializer {
  3. @Override
  4. public void onStartup(ServletContext container) {
  5. XmlWebApplicationContext appContext = new XmlWebApplicationContext();
  6. appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
  7. ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(appContext));
  8. registration.setLoadOnStartup(1);
  9. registration.addMapping("/");
  10. }
  11. }

Spring MVC提供了一个WebApplicationInitializer接口,实现这个接口能保证你的配置能自动被检测到并应用于Servlet 3容器的初始化中。WebApplicationInitializer有一个实现,是一个抽象的基类,名字叫AbstractDispatcherServletInitializer。有了它,要配置DispatcherServlet将变得更简单,你只需要覆写相应的方法,在其中提供servlet映射、DispatcherServlet所需配置的位置即可:

  1. public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
  2. @Override
  3. protected Class<?>[] getRootConfigClasses() {
  4. return null;
  5. }
  6. @Override
  7. protected Class<?>[] getServletConfigClasses() {
  8. return new Class[] { MyWebConfig.class };
  9. }
  10. @Override
  11. protected String[] getServletMappings() {
  12. return new String[] { "/" };
  13. }
  14. }

以上的例子适用于使用基于Java配置的Spring应用。如果你使用的是基于XML的Spring配置方式,那么请直接继承AbstractDispatcherServletInitializer这个类:

  1. public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {
  2. @Override
  3. protected WebApplicationContext createRootApplicationContext() {
  4. return null;
  5. }
  6. @Override
  7. protected WebApplicationContext createServletApplicationContext() {
  8. XmlWebApplicationContext cxt = new XmlWebApplicationContext();
  9. cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
  10. return cxt;
  11. }
  12. @Override
  13. protected String[] getServletMappings() {
  14. return new String[] { "/" };
  15. }
  16. }

AbstractDispatcherServletInitializer同样也提供了便捷的方式来添加过滤器Filter实例并使他们自动被映射到DispatcherServlet下:

  1. public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {
  2. // ...
  3. @Override
  4. protected Filter[] getServletFilters() {
  5. return new Filter[] { new HiddenHttpMethodFilter(), new CharacterEncodingFilter() };
  6. }
  7. }

每个过滤器被添加时,默认的名称都基于其类类型决定,并且它们会被自动地映射到DispatcherServlet下。

关于异步支持,AbstractDispatcherServletInitializer的保护方法isAsyncSupported提供了一个集中的地方来开关DispatcherServlet上的这个配置,它会对所有映射到这个分发器上的过滤器生效。默认情况下,这个标志被设为true

最后,如果你需要对DispatcherServlet做进一步的定制,你可以覆写createDispatcherServlet这个方法。