public interface WebApplicationInitializer
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.
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>
WebApplicationInitializer
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 you can see, thanks to Servlet 3.0's new
ServletContext#addServlet
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 componentry has 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.
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("/"); } }Remember that
WebApplicationInitializer
implementations are detected
automatically -- so you are free to package them within your application as you
see fit.
WebApplicationInitializer
executionWebApplicationInitializer
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
.
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.
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.
SpringServletContainerInitializer
Modifier and Type | Method and Description |
---|---|
void |
onStartup(ServletContext servletContext)
Configure the given
ServletContext with any servlets, filters, listeners
context-params and attributes necessary for initializing this web application. |
void onStartup(ServletContext servletContext) throws ServletException
ServletContext
with any servlets, filters, listeners
context-params and attributes necessary for initializing this web application. See
examples above.servletContext
- the ServletContext
to initializeServletException
- if any call against the given ServletContext
throws a ServletException