接口 WebApplicationInitializer

  • 所有已知实现类:
    AbstractAnnotationConfigDispatcherServletInitializer, AbstractContextLoaderInitializer, AbstractDispatcherServletInitializer

    public interface WebApplicationInitializer
    Interface to be implemented in Servlet 3.0+ environments in order to configure the ServletContext programmatically -- as opposed to (or possibly in conjunction with) the traditional web.xml-based approach.

    Implementations of this SPI will be detected automatically by SpringServletContainerInitializer, which itself is bootstrapped automatically by any Servlet 3.0 container. See its Javadoc for details on this bootstrapping mechanism.

    Example

    The traditional, XML-based approach

    Most Spring users building a web application will need to register Spring's DispatcherServlet. For reference, in WEB-INF/web.xml, this would typically be done as follows:
     
     <servlet>
       <servlet-name>dispatcher</servlet-name>
       <servlet-class>
         org.springframework.web.servlet.DispatcherServlet
       </servlet-class>
       <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/spring/dispatcher-config.xml</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>

    The code-based approach with WebApplicationInitializer

    Here is the equivalent DispatcherServlet registration logic, WebApplicationInitializer-style:
     public class MyWebAppInitializer implements WebApplicationInitializer {
    
        @Override
        public void onStartup(ServletContext container) {
          XmlWebApplicationContext appContext = new XmlWebApplicationContext();
          appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
    
          ServletRegistration.Dynamic dispatcher =
            container.addServlet("dispatcher", new DispatcherServlet(appContext));
          dispatcher.setLoadOnStartup(1);
          dispatcher.addMapping("/");
        }
    
     }
    As an alternative to the above, you can also extend from AbstractDispatcherServletInitializer. As you can see, thanks to Servlet 3.0's new ServletContext.addServlet(java.lang.String, java.lang.String) method we're actually registering an instance of the DispatcherServlet, and this means that the DispatcherServlet can now be treated like any other object -- receiving constructor injection of its application context in this case.

    This style is both simpler and more concise. There is no concern for dealing with init-params, etc, just normal JavaBean-style properties and constructor arguments. You are free to create and work with your Spring application contexts as necessary before injecting them into the DispatcherServlet.

    Most major Spring Web components have been updated to support this style of registration. You'll find that DispatcherServlet, FrameworkServlet, ContextLoaderListener and DelegatingFilterProxy all now support constructor arguments. Even if a component (e.g. non-Spring, other third party) has not been specifically updated for use within WebApplicationInitializers, they still may be used in any case. The Servlet 3.0 ServletContext API allows for setting init-params, context-params, etc programmatically.

    A 100% code-based approach to configuration

    In the example above, WEB-INF/web.xml was successfully replaced with code in the form of a WebApplicationInitializer, but the actual dispatcher-config.xml Spring configuration remained XML-based. WebApplicationInitializer is a perfect fit for use with Spring's code-based @Configuration classes. See @Configuration Javadoc for complete details, but the following example demonstrates refactoring to use Spring's AnnotationConfigWebApplicationContext in lieu of XmlWebApplicationContext, and user-defined @Configuration classes AppConfig and DispatcherConfig instead of Spring XML files. This example also goes a bit beyond those above to demonstrate typical configuration of the 'root' application context and registration of the ContextLoaderListener:
     public class MyWebAppInitializer implements WebApplicationInitializer {
    
        @Override
        public void onStartup(ServletContext container) {
          // Create the 'root' Spring application context
          AnnotationConfigWebApplicationContext rootContext =
            new AnnotationConfigWebApplicationContext();
          rootContext.register(AppConfig.class);
    
          // Manage the lifecycle of the root application context
          container.addListener(new ContextLoaderListener(rootContext));
    
          // Create the dispatcher servlet's Spring application context
          AnnotationConfigWebApplicationContext dispatcherContext =
            new AnnotationConfigWebApplicationContext();
          dispatcherContext.register(DispatcherConfig.class);
    
          // Register and map the dispatcher servlet
          ServletRegistration.Dynamic dispatcher =
            container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
          dispatcher.setLoadOnStartup(1);
          dispatcher.addMapping("/");
        }
    
     }
    As an alternative to the above, you can also extend from AbstractAnnotationConfigDispatcherServletInitializer. Remember that WebApplicationInitializer implementations are detected automatically -- so you are free to package them within your application as you see fit.

    Ordering WebApplicationInitializer execution

    WebApplicationInitializer implementations may optionally be annotated at the class level with Spring's @Order annotation or may implement Spring's Ordered interface. If so, the initializers will be ordered prior to invocation. This provides a mechanism for users to ensure the order in which servlet container initialization occurs. Use of this feature is expected to be rare, as typical applications will likely centralize all container initialization within a single WebApplicationInitializer.

    Caveats

    web.xml versioning

    WEB-INF/web.xml and WebApplicationInitializer use are not mutually exclusive; for example, web.xml can register one servlet, and a WebApplicationInitializer can register another. An initializer can even modify registrations performed in web.xml through methods such as ServletContext.getServletRegistration(String). However, if WEB-INF/web.xml is present in the application, its version attribute must be set to "3.0" or greater, otherwise ServletContainerInitializer bootstrapping will be ignored by the servlet container.

    Mapping to '/' under Tomcat

    Apache Tomcat maps its internal DefaultServlet to "/", and on Tomcat versions <= 7.0.14, this servlet mapping cannot be overridden programmatically. 7.0.15 fixes this issue. Overriding the "/" servlet mapping has also been tested successfully under GlassFish 3.1.

    从以下版本开始:
    3.1
    作者:
    Chris Beams
    另请参阅:
    SpringServletContainerInitializer, AbstractContextLoaderInitializer, AbstractDispatcherServletInitializer, AbstractAnnotationConfigDispatcherServletInitializer
    • 方法详细资料

      • onStartup

        void onStartup​(ServletContext servletContext)
                throws ServletException
        Configure the given ServletContext with any servlets, filters, listeners context-params and attributes necessary for initializing this web application. See examples above.
        参数:
        servletContext - the ServletContext to initialize
        抛出:
        ServletException - if any call against the given ServletContext throws a ServletException