한국어 | English | 日本語
Senior Web Application Developer (8.8+ years)
Tech & Dev
engineering
Focusing on web frontend and backend development

Spring MVC Architecture, Working Principles, and Processing Flow

Spring MVC Abstract
When I first started web development, Spring was a truly revolutionary framework that allowed me to easily set up and develop web application servers (WAS). Even as a new employee, I could create a controller with just a few lines of code, which filled me with awe for web developers from the pre-Spring era. However, this convenience came at the cost of numerous abstractions, ironically creating a dark age where I couldn't grasp the underlying web server concepts for a while. It was then I understood why Toby's Spring book was so thick. After that, I diligently studied, peeling back each layer of abstraction to get closer to the essence of Spring.
This article explores the evolution from Web Servers to Web Application Servers (WAS) and the advent of Spring. It delves into Spring's working principles, primarily focusing on Servlet, and the processing flow for client requests. Finally, it briefly touches upon the concepts of Interceptor and Filter.

Web Server (Static Pages)

Displays pages located on the server to users.

In the early days of the web, static documents (HTML) were stored on a server, and when a user requested one, the file would be downloaded and displayed in their browser. For example, if you wanted to view the hello.html document on a specific server like aaron.com, you would call aaron.com/hello.html in your browser. Some readers might have seen pages like the one below when a university professor distributed lecture materials using their research lab’s server.

Static Page from Web Server

This method required explicitly loading all files to be served into the actual server. If a user tried to access a file that didn’t exist on the server, a 404 Not Found Error would be returned. Servers that provide static pages to users in this manner are called Web Servers, and commonly encountered examples include Apache and Nginx.

Example) Nginx Request/Processing Flow

As an example of a Web Server, Nginx processes user requests through the following steps:

Web Server

Web Application (Dynamic Pages)

It dynamically generates and displays pages that are not pre-existing on the server to users for each request.

Web servers evolved beyond simply providing one-way services that share static documents with users. They began to receive requirements for interactive, bidirectional services such as user registration, writing posts, and viewing posts written by others. Like typical applications, this necessitated database connectivity and asynchronous API calls for dynamic page rendering based on user status. The server was no longer just returning static resources located on the server but began to dynamically create and return resources (pages) corresponding to the information requested by the user.

To handle application-like requirements on the web, it became necessary to connect the Web Server with programs developed in various languages to pass user requests from the server to the program. This method of connecting web servers and programs is called CGI (Common Gateway Interface), and it has been developed in various languages. In Java, the concept of a Servlet object emerged, connecting Web Server requests/responses with Java Applications.

Since a Servlet is created for each user request, managing Servlet resources for multiple requests became necessary. The component responsible for this is the Web Container, which is also referred to as a Servlet Container from the Servlet’s perspective.

Combining these two creates a Web Application.

Web Server

Example) Tomcat Request/Processing Flow

As an example of a Web Application, Tomcat processes user requests through the following steps:

Web Application

Compared to the Web Server diagram, everything added below the Web Server is related to the Web Container. Let’s examine it in reverse order, from bottom to top, starting with the Web Container. The names indicated in gray are actual class/interface names.

Now that we understand the configuration, let’s examine the web application startup procedure according to the diagram above.

During Initial Startup

During Request Processing

Spring Framework

As Java Servlet-based web application development became active, the Spring Framework emerged to facilitate Java web development by applying various design patterns. While early web applications handled requests by allocating a Servlet for each request to dynamically render pages, Spring processes requests by allocating Beans, which are smaller units than Servlets, for each request. This means that instead of having multiple Servlets, Spring uses a single Servlet (which, as we’ll discuss later, is the DispatcherServlet) and employs a diverse and large number of Beans in the backend to provide appropriate processing for requests.

Since Spring is fundamentally a framework that supports development by separating roles into three groups: Model, View, and Controller using the MVC model, even developers with no prior knowledge of design patterns can create web applications with excellent maintainability and reusability. Furthermore, because Spring provides everything needed for a web application through Bean configurations, such as JPA for database access, transactions, and security, any beginner can easily build a robust web application, provided they have a solid understanding. In fact, one of Spring’s strengths is the ability to build applications even without a deep understanding. This translates to maximum productivity for both junior and senior developers alike.

Spring MVC Concepts

To understand how Spring MVC operates, you only need to know about MVC and the Front Controller pattern (2-level Controller).

MVC (Model, View, Controller)

  1. When a user requests a page, the Controller receives the request that is appropriate for it.
  2. It retrieves/creates the Model, which contains the information needed for the requested page.
  3. It then generates the final page, the View, using the retrieved/created Model, and returns it to the user.

Front (2-level) Controller Pattern

In the MVC model described above, the part that receives requests is called the Controller.

The meaning of a 2-level Controller is as follows:

The foremost Tomcat single Servlet (DispatcherServlet) is called the Front Controller because it’s the first to receive requests. The subsequent Spring Controller Bean is called the Page Controller because it’s used for actual page generation.

Spring MVC Request/Processing Flow

During Initial Startup

First, let’s look at which objects are created and prepared when Spring + Tomcat first starts up. You can see that a Spring Container has been newly added beneath the Web Container.

Spring Web Application - 1. Init

As shown in the diagram above, connecting Spring to Tomcat requires two configurations in Tomcat’s configuration file, web.xml.

During Request Processing

After initial startup, Tomcat is ready to receive all requests through a single DispatcherServlet. Spring also has various Beans prepared in the Root WebApplicationContext for Controller Beans to return results. Now, let’s examine how user requests are processed. It might look a bit complex, but it’s just a slight extension of what we saw in the Initial Startup section, so there’s no need to be intimidated.

Spring Web Application - 2. Request

The keywords of Spring can be said to be IoC and DI. Simply put, while traditionally developers directly created objects using new and manually injected them, Spring allows developers to specify only the interface, and the ApplicationContext (= Spring Container, inheriting BeanFactory) creates objects called Beans and automatically injects them based on developer configurations. In Spring, basic Java objects are thus referred to and used as Beans.

From a web application perspective, Beans in Spring can be broadly categorized into two types as follows. Accordingly, the Spring Container that manages the lifecycle of these Beans is also divided into two parts.

Looking at the diagram above, you can see that another Spring Container 2 has been created under Spring Container 1, which was generated during initial startup. While not critically important, the terms ‘parent’ and ‘child’ indicate a hierarchical relationship between the two containers. It simply means that Beans in the child Servlet WebApplicationContext can reference Beans in the parent Root WebApplicationContext, but not vice-versa.


Request processing proceeds in the following flow. Let’s examine it according to the red lines (request) and green lines (response) in the diagram.

  1. The user requests a specific page (index.html) from the Web Server.
  2. The Web Server searches for index.html. Since it does not exist, it delegates the request to the Web Container (ServletContext).
  3. A) The ServletContext creates a single DispatcherServlet for any request (/) as defined in web.xml.
  4. The DispatcherServlet searches for a HandlerMapping to find the appropriate Spring Controller for the page requested by the user.
  5. The DispatcherServlet invokes the found Spring Controller Bean through a HandlerAdapter.
  6. The HandlerAdapter invokes the HelloController Bean.
  7. The HelloController utilizes Beans within the Root WebApplicationContext and returns the result to the DispatcherServlet.
  8. The DispatcherServlet receives the Controller’s result and generates the result page (= View) (index.html) via the ViewResolver.
  9. The DispatcherServlet returns the result page (= View) (index.html) to the user.

The code-level flow of the above process is well-organized in this blog link, which can be a good reference.

Thus, we have visually explored how Spring MVC receives, processes, and returns user requests. Having delved into such detail, you should now better understand the meaning of numerous methods and classes (e.g., invoke, DispatcherServlet, preHandle, postHandle) found in Spring log stack traces when exceptions occur in controllers or services.

Although this has been a long post, I’d like to delve a bit deeper: into Interceptors and Filters. The simple difference between them is whether they are managed by Servlet or by Spring. Understanding their order and timing of invocation will be greatly beneficial when learning/applying Spring Security later on. Of course, if you’ve found it challenging to get this far, I hope you’ll come back and read this section later.

Differences Between Spring Interceptor and Filter

Regardless of whether it’s Spring, any web application that provides services open to some users absolutely requires security. Spring Security not only offers modules and configurations related to login and sessions for easy use, but it also allows developers to add desired security elements—such as applying custom authentication modules or implementing different security processing based on the request URL—to be executed before the actual request is delivered to the Spring Controller. This is where Interceptor and Filter come into play.

Earlier, we learned that a web application using Spring is largely composed of two parts: Tomcat (Web Container) and Spring (Spring Container). You can understand that Interceptors and Filters are distinguished by their management entity and execution time, corresponding to these two components: Tomcat and Spring.

It’s perfectly fine as Filters are part of Servlet specification. Filters are called by your Server (Tomcat), while Interceptors are called by Spring^2

Below is a diagram illustrating the management entity and execution time of Interceptor and Filter for easy understanding.

Spring Web Application - 3. Filter and Interceptor

Filter (Tomcat)

Since the doFilter function is called twice—once upon request entry and once upon result return—it is suitable for global logic that needs to be processed both before the request and after the return, such as encryption/decryption.

Interceptor (Spring)

It is suitable for logic that needs detailed processing at the point of Controller entry or result return. For example, for requests entering a specific URL, URL-specific information can be pre-configured in the session just before Controller entry, allowing it to be used within the Controller’s internal logic. Conditions could also be added to prevent this logic from executing for other URLs.


It is important to note that because Filters and Interceptors have different management entities, the following situation can occur:

Since a Filter is not managed by the Spring Container, if you need to use Spring Beans within a Filter’s logic, you cannot use @Autowired for dependency injection. Instead, you must first obtain the Spring WebApplicationContext object and then directly retrieve and use the configured Beans within it through hardcoding.

Invocation Order of Multiple Interceptors and Filters

You can specify and use multiple Filters and Interceptors depending on the situation. When using multiple Filters or Interceptors, you can configure the invocation order for each group (Filters among themselves, Interceptors among themselves), but it is not possible to mix them in a pattern like Filter - Interceptor - Filter - Interceptor.

To understand the operational sequence when using two Filters and two Interceptors, let’s focus on DispatcherServlet and HandlerAdapter, as shown below.

Spring Filters and Interceptors

Briefly summarized, it follows the diagram/flow below.

Spring Filters and Interceptors - Summary

  1. doFilter (F1)
  2. doFilter (F2)
  3. preHandler (I1)
  4. preHandler (I2)
  5. Controller Request Processing
  6. postHandler (I2)
  7. postHandler (I1)
  8. View Rendering
  9. afterCompletion (I2)
  10. afterCompletion (I1)
  11. doFilter (F2)
  12. doFilter (F1)

We have explored the Web Server, Web Application, and then CGI as an example to connect the Web Server and Web Application, followed by Servlet and Container. Then, we delved into the Spring Container, the differences between Filter and Interceptor, and their execution order. I hope this article is helpful to other developers studying or using Spring. The referenced articles are also excellent, so I recommend taking a look at them if you have time.


  1. Spring Working Principles #1, #2, #3
  2. How Tomcat Calls Spring
  3. Java Servlet
  4. Differences Between Web Server and Web Application
  5. Spring DispatcherServlet Working Principles #1, #2
  6. Spring web.xml Explanation #1, #2
  7. Spring’s Two Types of ApplicationContext
  8. Servlet Container & Spring Container
  9. Spring MVC Code-Based Working Principles
Spring MVC Architecture, Working Principles, and Processing Flow
Author
Aaron
Posted on
Licensed Under
CC BY-NC-SA 4.0
CC BY-NC-SA 4.0
More in this category
Recent posts
The Erosion of Conversational Muscle and Communication Styles by LLM Filters
In an era where LLM tools, which filter out conversational impoliteness and deliver refined responses, have become commonplace, are we truly engaging in more thoughtful conversations? This article examines the phenomenon of conversational ability, which should be honed through countless failures in real-time communication, degenerating due to reliance on external tools. It further explores the potential societal anxieties and shifts in generational behavioral patterns that this trend may bring.
Optimal Timing and Strategy for Salary Negotiation with Senior Candidates
Salary negotiation is more than just an exchange of figures; it's a strategic dance of psychological timing. This analysis explores why engaging in a gradual negotiation process from the initial stages of recruitment, rather than waiting until after a final offer (when candidates tend to adopt a more calculative stance), proves more efficient for companies and fosters a more honest sharing of resources.
The Limits of the Rule of Law and Human Diversity
The belief that all human actions can be regulated by a single legal system may be an act of hubris. This article offers a sharp analysis of the paradox of the rule of law faced by humanity, which, having escaped the hierarchical controls of the Middle Ages, has now embraced infinite modern freedom. It further examines the deepening social coercion and the demonization of others that arise under the guise of diversity.
토스트 예시 메세지