How Spring Framework Ready The Server to Serve Http Requests

8 min readNov 20, 2023

Introduction

Spring is a framework used to build enterprise Java applications introduced as a flexible alternative technology to Java Servlets due to its higher learning curve and configuration complexity.

The complete process of Spring server initialization

In this story, I am going to explain the story of how Spring framework ready the server to handle HTTP requests in conjunction with the Java EE server with examples. In my examples, I have used the following versions for the following technologies.

  1. Java — Version 11
  2. Java EE — Java EE 8
  3. Java EE Implementation — Apache Tomcat 9

Assume you know the process of JavaEE servlet technology until the server is ready for getting requests from the moment of war file explosion.

The common Steps in Java servlet after the war file is exploded are as follows

  1. The logical deployment descriptor is being created
  2. WebServletContext is being created
  3. Listeners are being initialized
  4. Filters are being initialized
  5. Servlets are initialized
Major steps for Java Servlet technology
The major steps of the process of Java EE servlet technology

So it is clear that if Spring or some other 3rd party needs to conjunction with this process, Java servlet technology must provide a common entry point anywhere among these steps to implement frameworks or plugins.

Implementations for Other Frameworks and Plugins in Java Servlets

Following is the point that has been described in the official Servlet specification version 4.0.1. Just pay attention to the highlighted part.

ServletContainerInitializer

Java Servlet Specification v4.0.1 Section 8.2.4 — ServletContainerInitializer
Java Servlet Specification v4.0.1 Section 8.2.4 — ServletContainerInitializer

According to it, In between step 2 and step 3 above, Tomcat is searching for ServletContainerInitializer class at all the jar files included in the project if available. This class has to be stored exactly inside javax.servlet.ServiceContainerInitializer file which is placed in META-INF/services directory in each jar file.

javax.servlet.ServiceContainerInitializer file
javax.servlet.ServiceContainerInitializer file

Generally what Tomcat does is, if find class files in those directories, load them into the memory, and make instances of them.

@HandlesTypes

The next paragraph describes the next step of the process. In the ServletContainerInitializer, there is an annotation assigned called @HandlesTypes. The implementer can assign any class for it and Tomcat searches all the classes that have been extended or implemented to the assigned class. Just check the very next paragraph of the Java Servlet specification.

Java Servlet Specification v4.0.1 Section 8.2.4 — ServletContainerInitializer
Java Servlet Specification v4.0.1 Section 8.2.4 — @HandlesTypes

Then finally Tomcat makes a set of those all classes and invokes onStartUp( ) method of the instance of ServletContainerInitializer by passing the created set and the memory location of ServletContext.

Java Servlet implementation for other implementations
Java Servlet implementation for other implementations

How Spring Used This to Take Control

They have implemented a link for a class called SpringServletContainerInitializer that has implemented the ServletContainerInitializer interface in the META-INF/services/javax.servlet.ServiceContainerInitializer file in their web package. For the @HandlesTypes annotation, they have assigned an interface called WebApplicationInitializer.

Spring implementation for ServletContainerInitializer
Spring implementation for ServletContainerInitializer

When Tomcat makes a set of all the classes that have implemented the WebApplicationInitializer interface and invokes the onstartup( ) method of SpringServletContainerInitializer, Spring takes control of the further process from here.

Spring implementation graphical representation

To describe the further process I had to configure a new project which is spring-demo. The basic configurations for the project as below.

Basic Configuration for a Spring Project

First, there are 3 classes that have to be set which are WebRootConfig, WebAppConfig, and WebAppInitializer.

WebRootConfig

@Configuration annotation should be assigned to the WebRootConfig class.

WebAppConfig

@Configuration, @EnableWebMvc, @ComponentScan annotations should be assigned to WebAppConfig class.

WebAppInitializer

WebAppInitializer class should be extended to AbstractAnnotationConfigDispatcherServletIntitializer class and overridden 3 methods shown in the image, setting WebRootConfig to getRootConfigClasses( ) method and WebAppConfig class to getServletConfigClasses( ) method.

Not only those 3 classes but also, a controller class has to be set up as I have set a MyHttpController class.

MyHttpController

Specially, @RestController or @Controller annotation (I have selected @RestController) and @RequestingMapping annotations have to be assigned to this controller class and I have set “/hello” to @RequestMapping Annotation. Following, I have created an arbitrary method assigning the @GetMapping annotation which returns a String as response.

For experiment purposes, I have overridden all the constructors of those classes and set a static initializer to identify the class object initializing time and the moment of creating instances of them in the process of Spring server initializing. I have got a result as follows.

In summary, we can break down the above result into 5 major steps.

  1. WebAppInitializer class object has been initialized and created an instance
  2. WebRootConfig class object has been initialized and created an instance
  3. WebAppConfig class object has been initialized and created an instance
  4. Again a WebRootConfig instance has been created
  5. MyHttpController class object has been initialized and created an instance

Let’s explore how this process works

Major Steps in The Process

Initializing the WebApplicationInitializers

As I said earlier when Tomcat invokes the onStartUp( ) method of SpringServletContainerInitializer Spring takes the control of process. Here is the onStartUp( ) method below in the source code.

Inside the onStartUp( ) method, they iterate all the classes that came through the set that implemented the WebApplicationInitializer and make instances through Reflections.

As per the above class hierarchy, it is clear that the WebAppInitializer class also implements the WebApplicationInitializer interface and it also should be among the list of classes that iterates. That is how the WebAppInitializer class instance is created.

Initializing the RootApplicationContext

Spring invokes the onStartUp( ) method with the memory location of the ServletContext. According to the runtime polymorphism, onStartUp( ) method of the AbstractDispatcherServletInitializer class will work. Check the following code in the example.

In the first line of it, it says to invoke the onStartUp( ) method of the superclass.

As per the above code you can see, now the RootApplicationContext is created. this is how the RootConfig class object is initialized and the instance is created. The overall process up to now is as below.

Initializing the ServletApplicationContext

Now the DispatcherServlet registration process is started.

First of all, the ServletApplicationContext is initialized. This is how the WebAppConfig class object was initialized and the instance was created since the ServletApplicationContext is created based on the WebAppConfig same as the WebRootConfig did earlier with the RootApplicationContext.

Process up to now is as below graph.

Loading all the classes with the @Component annotation to the ServletApplicationContext and filling the RequestMappingHandlerMapping Registry

If you can remember, we have assigned another 2 annotations with the WebAppConfig class which are @ComponentScan and @EnableWebMvc. From them, the execution occurs in the following order.

  1. @ComponentScan
  2. @EnableWebMvc

@ComponentScan

In @ComponentScan, check all the classes that have the @Component annotation assigned and store them in the ServletApplicationContext.

Both @RestController and @Configuration annotations have the @Component annotation. So, MyHttpController, WebAppConfig, and WebRootConfig instances will be stored in the ServletApplicationContext.

Here WebAppConfig is already created with the born of ServletApplicationContext. So WebRootConfig and MyHttpController instances will be created and stored at this moment. Here is how the second instance of the WebRootConfig is created.

@EnableWebMvc

At @EnableWebMvc, they created a registry called RequestMappingHandlerMapping. Then they search all the classes with the @RequestMapping annotation and other Handlermappings within the ServletApplicationContext and store them in the registry.

You can see the graphical representation of the process up to now below.

Configuring the Dispatcher Servlet

Spring is also using one servlet to receive HttpRequests and send HttpResponses which is a Dispatcher Servlet.

At this moment of the process, the Dispatcher Servlet is created and registered in the ServletApplicationContext. After that, by the dynamic registration, the Dispatcher Servlet is registered in the ServletContext also.

Normally, when the ServletContext is created, it uses a Web.xml file or annotations to identify and store the Servlets inside. But Spring’s dispatcher servlet is not mentioned either in the Web.xml or through annotation. So ServletContext at the moment of creating isn’t aware of the dispatcher servlet. That is why it is required to use the dynamic registrations to store the dispatcher servlet in the ServletContext.

Inside the Dispatcher Servlet, there is a method called initServletBean( ). In that method, they have invoked initWebApplicationContext( ) method. Inside that method, the RootApplicationContext has been set as the parent of ServletAplicationContext.

Now we can again see the graphical interpretation of the process up to now.

This is the final step inside the Springs scope. If you can remember, the path was altered from the 2nd step of the process in the Servlet technology. With the completion of the Spring’s configurations, it is time to continue from the 3rd step which is initializing the listeners to the 5th step of initializing the Servlets.

Now the server is ready to handle HttpRequests. The complete graphical representation of the whole process can be seen now as already mentioned at the beginning of the article.

Please give your ideas about the article in the below comment section.

--

--

Shehan Rathnayake
Shehan Rathnayake

Written by Shehan Rathnayake

Software Engineer | Fueled by curiosity and dedication | Coding my way to excellence 🔥 | Exploring the World of Information Technology 🚀

Responses (2)