接口 WebApplicationInitializer
- 所有已知实现类:
AbstractAnnotationConfigDispatcherServletInitializer
,AbstractContextLoaderInitializer
,AbstractDispatcherServletInitializer
,AbstractReactiveWebInitializer
public interface WebApplicationInitializer
Interface to be implemented in Servlet 3.0+ environments in order to configure theServletContext
programmatically -- as opposed to (or possibly in conjunction with) the traditionalweb.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'sDispatcherServlet
. 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
Here is the equivalentWebApplicationInitializer
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 fromAbstractDispatcherServletInitializer
. As you can see, thanks to Servlet 3.0's newServletContext.addServlet(java.lang.String, java.lang.String)
method we're actually registering an instance of theDispatcherServlet
, and this means that theDispatcherServlet
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
andDelegatingFilterProxy
all now support constructor arguments. Even if a component (e.g. non-Spring, other third party) has not been specifically updated for use withinWebApplicationInitializers
, they still may be used in any case. The Servlet 3.0ServletContext
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 aWebApplicationInitializer
, but the actualdispatcher-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'sAnnotationConfigWebApplicationContext
in lieu ofXmlWebApplicationContext
, and user-defined@Configuration
classesAppConfig
andDispatcherConfig
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 theContextLoaderListener
: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 fromAbstractAnnotationConfigDispatcherServletInitializer
. Remember thatWebApplicationInitializer
implementations are detected automatically -- so you are free to package them within your application as you see fit.Ordering
WebApplicationInitializer
executionWebApplicationInitializer
implementations may optionally be annotated at the class level with Spring's @Order
annotation or may implement Spring'sOrdered
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 singleWebApplicationInitializer
.Caveats
web.xml versioning
WEB-INF/web.xml
andWebApplicationInitializer
use are not mutually exclusive; for example, web.xml can register one servlet, and aWebApplicationInitializer
can register another. An initializer can even modify registrations performed inweb.xml
through methods such asServletContext.getServletRegistration(String)
. However, ifWEB-INF/web.xml
is present in the application, itsversion
attribute must be set to "3.0" or greater, otherwiseServletContainerInitializer
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.
方法概要
所有方法 实例方法 抽象方法 修饰符和类型 方法 说明 void
onStartup(ServletContext servletContext)
Configure the givenServletContext
with any servlets, filters, listeners context-params and attributes necessary for initializing this web application.
方法详细资料
onStartup
void onStartup(ServletContext servletContext) throws ServletException
Configure the givenServletContext
with any servlets, filters, listeners context-params and attributes necessary for initializing this web application. See examples above.- 参数:
servletContext
- theServletContext
to initialize- 抛出:
ServletException
- if any call against the givenServletContext
throws aServletException