Spring WebApplicationInitializer and ApplicationContextInitializer confusion
These are two concepts that I mix up occasionally – a WebApplicationInitializer and an ApplicationContextInitializer, and wanted to describe each of them to clarify them for myself.
I have previously blogged about WebApplicationInitializer 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.
Reference: | Spring WebApplicationInitializer and ApplicationContextInitializer confusion from our JCG partner Biju Kunjummen at the all and sundry blog. |
We are using Spring Integration heavily here at my present job. What we mainly do is create an embedded WebAppliction server from Jetty or another embeddable web application server. We make a ServiceActivator that wraps the web application server, so it’s transparent to the SI application. Once this is done, most of our web applications are Web Service Calls. Doing this, we use your method of an ApplicationContextInitializer singleton to give the Web Services access to the context. It’s a very simple practice and works for WebApplications. I don’t know how it would work for high volume web sites, but… Read more »