How does Spring initialize under the hood ? — Part 2
By: Minh-Luan H. Phan
Tags: Java, Spring Framework, Web Development, Backend Development, Programming

Main Discussion

interface WebApplicationInitializer

Any class implement this Interface will be scanned by Spring Container on application startup. This class only has 1 role: to assemble the web application’s moving part in lieu of configuring by xml .

I think you will have a question. How the method onStartUp(ServletContext) is invoked. The details will be revealed on my next topic, stay tune.

First, when we run the application, the Spring Container will call onStartUp(ServletContex) of WebApplicationInitializer . In this method, 2 other methods will be invoked, registerContextLoaderListener(ServletContext) of abstract class AbstractContextLoaderListener to create Root Application Context and registerDispatcherServlet(ServletContext) of abstract class AbstractDispatcherServletInitializer to create Dispatcher Servlet. We will explore these methods below.

AbstractContextLoaderInitializer

The class name obviously reveals its function. This abstract class is to register ContextLoaderListener with the Servlet Context.

ContextLoaderListener is to construct listener for Servlet Context. The role of this class is to receive notifications about changes to the Servlet Context of the web application.

In ContextLoaderListener , we have 2 important methods which is overridden from interface ServletContextListener ( javax.servlet ):

contextInitialized() : get called before any servlet's init() method or any filter's doFilter() method

: get called before any servlet's method or any filter's doFilter() method contextDestroyed() : get called after the servlet's or filter's destroy() method.

AbstractDispatcherServletInitializer

This class is to create Dispatcher Servlet and be added to Servlet Context

n registerDispatcherServlet(ServletContext) :

Servlet’s name will be received through getServletName() (this method can be overridden, if don't, its name will be 'dispatcher-servlet ').

Method createServletApplicationContext() will be called and return a WebApplicationContext object (this method is implemented in abstract class AbstractAnnotationConfigDispatcherServlet which will be discussed below).

Dispatcher Servlet will be created as an object inherited from parent class FrameworkServlet . FrameworkServlet is a base servlet for Spring framework and it provides integration with WebApplicationContext .

AbstractAnnotationConfigDispatcherServletInitializer

This abstract class is a direct parent class of any configuration class created by us.

In createRootApplicationContext() , method getRootConfigClasses() of AbstractAnnotationConfigDispatcherServletInitializer will be invoked. That method contains any classes related to initialize root application context.

In createServletApplicationContext() , similar to createRootApplicationContext() , it also receives config classes from getServletConfigClasses() .

But the difference is the return value of createRootApplicationContext() and createServletApplicationContext() . While the former one can be null, the latter one cannot. Because Spring MVC application needs to have at least one Dispatcher Servlet to receive request from client, handle mapping to controller and then response to client.

So, if you have a single Dispatcher Servlet application, you only need to config either the root one or servlet one. By benefiting the difference of 2 method, it is easy to create a multiple Dispatcher Servlet application which serves multiple purpose. For example, you can separate which servlet will handle api request, or which one will handle an application with MVC pattern. Api request or application with MVC pattern may have some common configurations like HibernateConfig or SecurityConfig (which will be declare in createRootApplicationContext() ) and some different resources like Controller (which will be declare in createServletApplicationContext() because RestController doesn't need configurations like ViewResovler but it need Jackson to parse Object to JSON).

I will show you how to create multiple Dispatcher Servlets application in another topic.

MyApplicationInitializer

This is our custom configuration class which has 3 methods being overridden from abstract class AbstractAnnotationConfigDispatcherServletInitializer .

Sum Up

Being inherited and implemented a lot of abstract classes and interfaces may make you confuse a little bit. This is the order of what is actually happened. You can see code below.

a simple workflow of initializing a Spring Application

References