In web application development, an interceptor is a very important mechanism that can perform pre- and post-processing at all stages of request processing. The Spring framework provides a powerful and flexible interceptor mechanism that enables developers to easily insert custom logic into request processing flows.
Understanding the implementation principle of Spring intercept chains will not only help us better use the functions provided by Spring, but also allow us to customize complex request processing logic when needed.
1. What is an interceptor chain?
Simply put, an interceptor chain is a list of interceptors that process requests, intercepting and processing requests one by one in a certain order. Each interceptor can execute some logic before, after, or after the request is processed.
For example, we may need to perform permission verification before all requests are processed, log the log after processing, or release the resource after the request is completed. These operations can be achieved by defining different interceptors, each responsible for a specific task.
2. Intercept chain in Spring
In Spring MVC, the interceptor chain is throughHandlerInterceptor
Interfaces and implementation classes are implemented. Spring'sDispatcherServlet
As a front controller, it is responsible for coordinating various stages of requests, including calling interceptors.
The implementation of the interceptor chain allows multiple interceptors to process requests in a certain order. Each interceptor has the opportunity to execute specific logic before and after request processing, which provides great flexibility for us to insert custom logic into the request processing flow.
3. The core components of the intercept chain
To understand the implementation principle of intercepting chains, you first need to understand the role and relationship between several core components in Spring MVC:
HandlerMapping:HandlerMapping
Responsible for mapping the request URL to a specific processor (Handler). A processor is usually a controller method. Spring offers a variety ofHandlerMapping
Implementation, such asRequestMappingHandlerMapping
, supports annotation-based mapping.
HandlerAdapter:HandlerAdapter
It is the component responsible for executing a specific processor. It knows how to call a specific type of processor and returns aModelAndView
Object, used to render views.
DispatcherServlet:DispatcherServlet
It is the core component of Spring MVC and serves as the current controller. It receives all HTTP requests and coordinatesHandlerMapping
、HandlerAdapter
Components such as view resolution will eventually distribute the request to the appropriate processor for processing.
HandlerInterceptor:HandlerInterceptor
The interface defines the basic behavior of the interceptor. By implementing this interface, custom logic can be inserted at different stages of request processing, such as before, after request, or after completion processing.
4. The workflow of intercepting chains
After understanding the core components, let's look at how interceptor chains collaborate among these components.
-
Request to arrive at DispatcherServlet: All HTTP requests are first made by
DispatcherServlet
take over. -
Find Handler:
DispatcherServlet
useHandlerMapping
Find a processor (Handler) that matches the request URL. -
Apply interceptor front: Before calling the processor,
DispatcherServlet
Will call all registered interceptorspreHandle
method. These interceptors are executed in sequence in the defined order. If any interceptorpreHandle
returnfalse
, the request will be terminated and subsequent interceptors and processors will not execute. -
Call HandlerAdapter to execute Handler: All pre-interceptors
preHandle
Method returntrue
back,DispatcherServlet
Will callHandlerAdapter
Execute specific processor methods (such as those in Controller). -
Apply interceptor rear: After the processor is executed,
DispatcherServlet
Will call the interceptorpostHandle
Methods, these interceptors are executed in reverse order in the defined order. -
Rendering view:
DispatcherServlet
Use a view resolver (ViewResolver) to render the final view, such as returning an HTML page. -
Complete the interceptor:at last,
DispatcherServlet
Calling the interceptorafterCompletion
Method, notify the interceptor request has been completed and the same is executed in reverse order.
This process ensures that the interceptor can insert logic at different stages of request processing, such as verification, logging, performance monitoring, etc.
5. Source code analysis
To deeply understand the implementation principle of intercept chains, we need to check the source code of Spring MVC. Below, we will analyze it step by stepDispatcherServlet
、HandlerMapping
、HandlerAdapter
andHandlerInterceptor
The source code of components such as the implementation of the comprehensive understanding of the intercept chain.
5.1 The role of DispatcherServlet
DispatcherServlet
It is the central hub of the entire Spring MVC request processing process. It undertakes tasks such as receiving requests, finding processors, executing interceptors, calling processors, rendering views, etc.
Let's seeDispatcherServlet
Key source code related to intercept chains.
public class DispatcherServlet extends FrameworkServlet { // ...Other codes... @Override protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { // ...Initialization context... // 1. Find the processor HandlerExecutionChain mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(request, response); return; } HttpServletRequest webRequest = createWebRequest(request, response); try { // 2. Apply the preHandle method of the interceptor HandlerInterceptor[] interceptors = (); if (!applyPreHandle(processedRequest, response, mappedHandler, interceptors)) { return; } // 3. Call the processor ModelAndView mv = (processedRequest, response, ()); // 4. Apply the postHandle method of the interceptor applyPostHandle(processedRequest, response, mappedHandler, mv, interceptors); // 5. Render view render(mv, request, response); // 6. Apply the afterCompletion method of the interceptor triggerAfterCompletion(processedRequest, response, mappedHandler, null, interceptors); } catch (Exception ex) { // Exception handling // ... } } // ...Other codes...}
As can be seen from the above code,DispatcherServlet
During the process of processing the request, the search processor and the application interceptor are executed in turn.preHandle
, calling processors, applying interceptorspostHandle
, rendering views and applying interceptorsafterCompletion
Steps of the method.
5.2 HandlerMapping search mechanism
HandlerMapping
Used to map requests to specific processors. Spring MVC provides a variety ofHandlerMapping
Implementation, such as annotation-basedRequestMappingHandlerMapping
。
Let's see a simple onegetHandler
Method implementation:
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { return (request); }
here,handlerMappings
It's oneList<HandlerMapping>
, Spring will traverse these in orderHandlerMapping
, until a matching processor is found.
RequestMappingHandlerMapping
A core approach isgetHandlerInternal
:
@Override protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { // Find matching HandlerMethod based on request URL and HTTP methods // Return a HandlerMethod object, containing controller instance and method information}
5.3 HandlerAdapter adaptation logic
HandlerAdapter
Responsible for calling the specific processor. Spring MVC provides a variety ofHandlerAdapter
Implementation, such asRequestMappingHandlerAdapter
。
have a lookgetHandlerAdapter
andhandle
method:
protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return (request, response, handler); }
handlerAdapter
It's oneHandlerAdapter
The implementation of the interface is throughsupports
The method determines whether it is adapted and then callshandle
Method executes the processor.
RequestMappingHandlerAdapter
ofhandle
Method example:
@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // Call Controller method to process the request // Bind request parameters, perform data binding and verification // Return the ModelAndView object}
5.4 HandlerInterceptor execution process
existDispatcherServlet
ofdoDispatch
In the method, we see the call flow of the interceptor. Let's take a closer look at how these interceptors are executed.
Suppose we have oneHandlerExecutionChain
Object, which contains the processor and a set of interceptors:
public class HandlerExecutionChain { private final Object handler; private final List<HandlerInterceptor> interceptors; // Getters and constructors }
existapplyPreHandle
In the method,DispatcherServlet
Each interceptor will be called in sequencepreHandle
method:
protected boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler) throws Exception { HandlerInterceptor[] interceptors = (); if(!(interceptors)) { for (HandlerInterceptor interceptor : interceptors) { if (!(request, response, ())) { triggerAfterCompletion(request, response, mappedHandler, null, interceptors); return false; } } } return true; }
Similarly, inapplyPostHandle
andtriggerAfterCompletion
In the method, the interceptorpostHandle
andafterCompletion
The methods are called in sequence, in orderpreHandle
on the contrary.
6. Implementation of custom interceptors
After understanding the basics of intercepting chains, let's take a look at how to customize interceptors in Spring. Here is a simple custom interceptor example:
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // Execute before request processing ("Pre Handle method is Calling"); return true; // Return true to continue the process, return false to interrupt } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // After the request is processed, but before the view is rendered ("Post Handle method is Calling"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // Execute after rendering the view ("Request and Response is completed"); } }
Registering this interceptor can be configured through Java or XML. In Spring Boot, it can be implemented byWebMvcConfigurer
Interface configuration:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { (new MyInterceptor()) .addPathPatterns("/**") // Intercept all requests .excludePathPatterns("/login"); // Exclude specific paths } }
With such a configuration,MyInterceptor
It will intercept all requests except/login
path.
6.1 The order of execution of interceptors
If multiple interceptors are defined, Spring will be executed in the order of registrationpreHandle
method, and executepostHandle
andafterCompletion
It is in reverse order. For example:
@Override public void addInterceptors(InterceptorRegistry registry) { (new FirstInterceptor()); (new SecondInterceptor()); }
Execution order:
This design allows post-registered interceptors to perform post-logic and completion logic first.
7. Summary
In this article, we have discussed in-depth the implementation principle and source code analysis of Spring intercept chains, from core components such asDispatcherServlet
、HandlerMapping
、HandlerAdapter
andHandlerInterceptor
functions, to the workflow of the intercept chain, to actual source code analysis and custom interceptor implementation.
Understanding these principles not only helps us better use the interceptor functions provided by Spring, but also allows us to customize complex interception logic when needed, enhancing application flexibility and maintainability.
This is the end of this article about a detailed explanation of the implementation principle of Spring intercept chain. For more related contents of Spring intercept chains, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!