How does Spring initialize under the hood ? — Part 2
Have you ever wondered what is actually happened when you click Run a Spring Application?
After a couple of days of deep delving these configuration classes, I understood (a little bit) how this framework initializes a Spring application.
Moreover, I appreciate every comment which build this topic up. It would be my honor when this topic brings to you some valuable knowledge.
I encourage you to delve these abstract classes and interfaces in your IDE to have a deep understanding of this framework. Believe me, it is absolutely awesome. And if you observe something cool about Spring, just comment below, it is the best to learn from each other.
My Contact
- Facebook: Phan Hoang Minh Luan
- LinkedIn: Phan Hoang Minh Luan
- Email: phanhoangminhluan@gmail.com
Warm Up
The lowest class is our custom configuration. To simplify and keep you on track with what I did, I have removed some unused method as well as some line of codes which do not influence to our demo.
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'sinit()
method or any filter's doFilter() methodcontextDestroyed()
: get called after the servlet's or filter'sdestroy()
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.