I have previously blogged about WebApplicationInitializer here and here. It is relevant purely in a Servlet 3.0+ spec compliant servlet container and provides a hook to programmatically configure the servlet context. How does this help - you can have a web application without potentially any web.xml file, typically used in a Spring based web application to describe the root application context and the Spring web front controller called the DispatcherServlet. An example of using WebApplicationInitializer is the following:
public class CustomWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{RootConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{MvcConfiguration.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
Now, what is an ApplicationContextInitializer. It is essentially code that gets executed before the Spring application context gets completely created. A good use case for using an ApplicationContextInitializer would be to set a Spring environment profile programmatically, along these lines:
public class DemoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext ac) {
ConfigurableEnvironment appEnvironment = ac.getEnvironment();
appEnvironment.addActiveProfile("demo");
}
}
If you have a Spring-Boot based application then registering an ApplicationContextInitializer is fairly straightforward:
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SampleWebApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SampleWebApplication.class)
.initializers(new DemoApplicationContextInitializer())
.run(args);
}
}
For a non Spring-Boot Spring application though, it is a little more tricky, if it is a programmatic configuration of web.xml, then the configuration is along these lines:
public class CustomWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootConfiguration.class);
ContextLoaderListener contextLoaderListener = new ContextLoaderListener(rootContext);
container.addListener(contextLoaderListener);
container.setInitParameter("contextInitializerClasses", "mvctest.web.DemoApplicationContextInitializer");
AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
webContext.register(MvcConfiguration.class);
DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext);
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", dispatcherServlet);
dispatcher.addMapping("/");
}
}
If it a normal web.xml configuration then the initializer can be specified this way:
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.myapp.spring.SpringContextProfileInit</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
So to conclude, except for the Initializer suffix, both WebApplicationInitializer and ApplicationContextInitializer serve fairly different purposes. Whereas the WebApplicationInitializer is used by a Servlet Container at startup of the web application and provides a way for programmatic creating a web application(replacement for a web.xml file), ApplicationContextInitializer provides a hook to configure the Spring application context before it gets fully created.