Spring WebApplicationInitializer provides a programatic way to configure the Spring DispatcherServlet and ContextLoaderListener in Servlet 3.0+ compliant servlet containers. But how does it work? How servlet container finds WebApplicationInitializer implementations, is it really load all classes from classpath?
Mostly, developers use AbstractAnnotationConfigDispatcherServletInitializer , which is an implementation of the WebApplicationInitializer , to create Spring web applications. Traditionally, Java web applications based on Servlets were using web. xml file to configure a Java web application.
This interface is used for booting Spring web applications. WebApplicationInitializer registers a Spring DispatcherServlet and creates a Spring web application context. Traditionally, Java Web Applications based on Servlets were using the web. xml file to configure a Java Web Application.
Spring's web MVC framework is, like many other web MVC frameworks, request-driven, designed around a central Servlet that dispatches requests to controllers and offers other functionality that facilitates the development of web applications. Spring's DispatcherServlet however, does more than just that.
In a Spring Boot application, the servlet is registered either as a Spring @Bean or by scanning the @WebServlet annotated classes with an embedded container. With the Spring @Bean approach, we can use the ServletRegistrationBean class to register the servlet.
I assume you have knowledge about java SPI and the way java.util.ServiceLoader a utility class used to load implementations. Else please read it.
But in brief for the this answer just understand : if there is one SPI, here javax.servlet.ServletContainerInitializer
,
then the provider should implement it and implementation must be declared in a META-INF/services/javax.servlet.ServletContainerInitializer file of the libraries jar file - Spring is such a provider and
declares this in spring-web*.jar jar file and has an entry org.springframework.web.SpringServletContainerInitializer
Then the service loader for ServletContainerInitializer can load the implementation. This loading is specific to ServletContainer implementation
I will explain this specific to tomcat7+ ServletContainer.
Tomcat has LifecycleListeners those will listen to lifecycle events like start,stop etc.
org.apache.catalina.startup.ContextConfig
is such a startup event listener for a ServletContext that configures the properties of that ServletContext, and the associated defined servlets.
So while tomcat initilizes a ServletContext
for a web application, it will generate such an event which will notify the ContextConfig
's even listening method. Then it will trigger
its own processServletContainerInitializers method, which scan JARs for ServletContainerInitializer implementations.
It does this via delegating this duty to WebappServiceLoader (a variation of Java's JAR ServiceLoader), who is actually responsible for the loading of ServletContainerInitializer implementaions from WEB-INF/lib jars.
So as conclusion the control flow would be like this.
Tomcat initialize the ServletContext
ContextConfig
is notified with this context startup event
service loading is delegated to
WebappServiceLoader<ServletContainerInitializer>
WebappServiceLoader scans in WEB-INF/lib jars for the file META-INF/services/javax.servlet.ServletContainerInitializer inorder to load the implementation
SpringServletContainerInitializer
)
onStartup method which will do rest of the things.HTH!
From docs:
Implementations of this SPI will be detected automatically by
SpringServletContainerInitializer , which itself is bootstrapped automatically by any Servlet 3.0 container. See SpringServletContainerInitializer or details on this bootstrapping mechanism.
and:
Mechanism of Operation
SpringServletContainerInitializerThis class will be loaded and instantiated and have its onStartup method invoked by any Servlet 3.0-compliant container during container startup assuming
that the spring-web module JAR is present on the classpath. This occurs through the JAR Services API {@link ServiceLoader#load(Class)} method detecting the spring-web module's META-INF/services/javax.servlet.ServletContainerInitializer
service provider configuration file.See the http://download.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider JAR Services API documentation as well as section 8.2.4 of the Servlet 3.0 Final Draft specification for complete details.
It is all in docs basically it's part of Servlet specs to detect SpringServletContainerInitializer
which implements ServletContainerInitializer
so its all down to container doing its job detecting these classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With