Spring WebApplicationInitializer

In this article, we will get an understanding of Spring WebApplicationInitializer interface along with a detailed analysis of the benefits and configurations of Spring WebApplicationInitializer.

Introduction

Dispatcher Servlet is known as an entry point for Spring MVC based web applications, you can think of Dispatcher Servlet as a gatekeeper for MVC application responsible to understand the request, send it to correct place and responsible to send the response back to the calling party.

Spring 3.1 Brough support for the Servlet 3 API, before that we can only register Servlet Dispatcher with Servlet container via the standard Web application web.xml file.

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>Spring3 MVC Application</display-name> <servlet> <servlet-name>spring-web</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring-web</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>

With Spring support for Servlet 3.0 Specification , web.xml is optional and we can manage all our web application using Java Annotations.

One of the natural questions will arise in your mind is “If we are not registering Dispatcher Servlet than how Spring will create/bootstrap Dispatcher Servlet for our application?“

Spring WebApplicationInitializer is the answer to your above question which was introduced with Spring 3.1.

1. What is Spring WebApplicationInitializer?

Spring WebApplicationInitializer is Servlet 3.0 + implementation to configure ServletContext programmatically in comparison to the traditional way to do this using web.xml .

2. Hybrid Configuration

We have 2 ways to replace traditional web.xml using Spring WebApplicationInitializer, in this one we will discuss a mix of replacing configuration using Java Annotation and XML based Spring configuration.

public class CustomWebAppInitializer implements WebApplicationInitializer { /** * Configure the given {@link ServletContext} with any servlets, filters, listeners * context-params and attributes necessary for initializing this web application. See examples * {@linkplain WebApplicationInitializer above}. * * @param servletContext the {@code ServletContext} to initialize * @throws ServletException if any call against the given {@code ServletContext} throws a {@code * ServletException} */ @Override public void onStartup(ServletContext servletContext) throws ServletException { XmlWebApplicationContext applicationContext = new XmlWebApplicationContext(); applicationContext.setConfigLocation("location of spring config xml file"); //Dispatcher servlet configuration ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(applicationContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); }

Above approach looks good, clean and preferred way to do it but this is not purely Java code based approach as we are still using web.xml in our code to read this configuration.

3. WebApplicationInitializer With Java Annotation

Let’s change our previous code to purely Java Annotation-based configuration.We will try to use Spring @Configuration classes in place of traditional XmlWebApplicationContext .

public class CustomWebAppInitializer implements WebApplicationInitializer { /** * Configure the given {@link ServletContext} with any servlets, filters, listeners * context-params and attributes necessary for initializing this web application. See examples * {@linkplain WebApplicationInitializer above}. * * @param servletContext the {@code ServletContext} to initialize * @throws ServletException if any call against the given {@code ServletContext} throws a {@code * ServletException} */ @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(Application.class); // Manage the lifecycle of the root application context servletContext.addListener(new ContextLoaderListener(rootContext)); // Register and map the dispatcher servlet ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } }

Let’s try to understand above example for better clarity.

As we are using Java-based annotation in place for XML configuration, we are going to use AnnotationConfigWebApplicationContext for this

AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

We need to register our context, this can be easily done by registering our custom configuration class.

rootContext.register(Application.class);

Let’s say your custom configurations are spread across multiple classes and you want to use all of these configurations, Spring WebApplicationInitializer provide a way to specify root package to be scanned for configuration classes.

rootContext.setConfigLocation("com.javadevjournal.app.config");

the application context is in place now, next step is to add our ContextLoaderListner to the ServletContext which will be responsible to load the context

// Manage the lifecycle of the root application context servletContext.addListener(new ContextLoaderListener(rootContext));

The final step of our example is creating and registering Dispatcher servlet, which is the entry point of our application.

// Register and map the dispatcher servlet ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/");

3.1 Web.xml and Java Annotation Caveats

Please be aware of the fact that web.xml and Spring WebApplicationInitializer configurations are not mutually exclusive, this means you can register one servlet in your application’s web.xml while you can use WebApplicationInitializer to register another servlet for your application.In case you have a web.xml file under WEB-INF/web.xml , it’s version must be set to 3.0 or greater else ServletContainerInitializer will completely ignore your web.xml file.

Annotation-based configurations offer a lot of advantages and these configurations are now becoming de facto standards for the new Spring-based applications, annotations are more concise and they normally add clear context to the declaration, however, there are certain cases where this is not a preferred way

I still want to separate out my code and configurations

Any third party solution which is outside of our control and we can not customize it.

Summary

In this article, We got an understanding of Spring WebApplicationInitializer interface. we covered traditional way to initialize our Spring application. We covered mix way (use configuration and annotation) for our application configuration. In the last part, we covered the new way (100% java base) configuration.

Spring WebApplicationInitializer is really powerful and with new Servlet 3.0 specification, it provides a more flexible way to configure our application. In the next article, we will be covering web.xml and Initializer in more detail.