Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Source code analysis of SpringBoot interceptor

2025-03-04 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

In this article Xiaobian for you to introduce in detail the "SpringBoot interceptor source code analysis", the content is detailed, the steps are clear, the details are handled properly, I hope this "SpringBoot interceptor source code analysis" article can help you solve your doubts, following the editor's ideas slowly in depth, together to learn new knowledge.

1. What is the interceptor

The Interceptor in java is an object that dynamically intercepts Action calls. It provides a mechanism that enables developers to execute a piece of code before and after the execution of an Action, or to prevent the execution of an Action before it is executed. It also provides a way to extract the reusable part of the code in Action. In AOP, interceptors are used to intercept a method or field before it is accessed, and then add certain actions before or after.

The Action above generally refers to the interface of our Controller layer.

2. Custom interceptor

Generally, a custom interceptor is divided into three steps.

(1) write an interceptor to implement the HandlerInterceptor interface.

(2) the interceptor is registered in the container.

(3) configure interception rules.

2.1 write interceptor

We create a new SpringBoot project, and then customize an interceptor LoginInterceptor to intercept some requests that are not logged in. Starting with JDK1.8, the method of an interface plus the default keyword can have a default implementation, so you only need to implement a method without the keyword to implement an interface.

Import lombok.extern.slf4j.Slf4j;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse / * Login interceptor * / @ Slf4jpublic class LoginInterceptor implements HandlerInterceptor {/ * execute * @ param request * @ param response * @ param handler * @ return * @ throws Exception * / @ Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {/ / get the request path String requestUrl = request.getRequestURI () before the target method executes Log.info ("request path is: {}", requestUrl); String username = request.getParameter ("username"); if (username! = null) {/ / release return true;} request.setAttribute ("msg", "Please sign in first") / take msg to the login page request.getRequestDispatcher ("/") .forward (request, response); return false } / * execute * @ param request * @ param response * @ param handler * @ param modelAndView * @ throws Exception * / @ Override public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info ("postHandle execution") after the target method is completed Execute * @ param request * @ param response * @ param handler * @ throws Exception * / @ Override public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info ("afterCompletion execution") after page rendering;} 2.2 Register and configure the interceptor

In SpringBoot, when we need to customize the configuration, we just need to implement the WebMvcConfigurer class to override the corresponding method. Here we need to configure the interceptor, so override its addInterceptors method.

Import com.codeliu.interceptor.LoginInterceptor;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer / / indicates that this is a configuration class @ Configurationpublic class WebMvcConfig implements WebMvcConfigurer {@ Override public void addInterceptors (InterceptorRegistry registry) {registry.addInterceptor (new LoginInterceptor ()) .addPathPatterns ("/ * *") / / intercept all paths. paths ("/", "/ login", "/ css/**", "/ fonts/**", "/ images/**", "/ js/**") / / do not block these paths}}

Note that if we are configured to block all paths, then static resources must be excluded, otherwise the image style will be blocked.

Through the above steps, we have implemented an interceptor to the system. Just start the verification.

3. The principle of interceptor

Let's take a look at how the browser request is processed from the browser request to the back end by breaking point debugging. Enter a breakpoint in the doDispatch method of DispatcherServlet, which is the entry point of the request. After the request is sent by the browser, it is forwarded and processed by this method.

Debug mode starts the application, accesses any interface, and tracks the code flow

3.1find all interceptors of handler and handler that can process requests

Here we find HandlerExecutionChain and the interceptor chain, which contains three interceptors, our custom LoginInterceptor and the system's default two interceptors.

3.2Executing the preHandle method of interceptor

In the doDispatch method, there are two lines of code

/ / execute the preHandle method of the interceptor. If fasle is returned, the target method if (! mappedHandler.applyPreHandle (processedRequest, response)) {return;} / / reflection executes the target method mv = ha.handle (processedRequest, response, mappedHandler.getHandler ()).

Let's go into the applyPreHandle method and look at the logic of the method

/ * Apply preHandle methods of registered interceptors. * @ return {@ code true} if the execution chain should proceed with the * next interceptor or the handler itself. Else, DispatcherServlet assumes * that this interceptor has already dealt with the response itself. * / boolean applyPreHandle (HttpServletRequest request, HttpServletResponse response) throws Exception {/ / traversing interceptor for (int I = 0; I

< this.interceptorList.size(); i++) { HandlerInterceptor interceptor = this.interceptorList.get(i); // 执行当前拦截器的preHandle方法 if (!interceptor.preHandle(request, response, this.handler)) { // 如果preHandle方法返回为false,则执行当前拦截器的afterCompletion方法 triggerAfterCompletion(request, response, null); return false; } // 记录当前拦截器的下标 this.interceptorIndex = i; } return true;} 通过上面的代码, 我们知道如果当前拦截器的preHandle方法返回为true,则会继续执行下一拦截器的preHandle方法,否则执行拦截器的afterCompletion方法。 那么我们看看triggerAfterCompletion方法的逻辑。 /** * Trigger afterCompletion callbacks on the mapped HandlerInterceptors. * Will just invoke afterCompletion for all interceptors whose preHandle invocation * has successfully completed and returned true. */void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) { // 反向遍历拦截器 for (int i = this.interceptorIndex; i >

= 0; iMel -) {HandlerInterceptor interceptor = this.interceptorList.get (I); try {/ / execute the afterCompletion method interceptor.afterCompletion (request, response, this.handler, ex) of the current interceptor;} catch (Throwable ex2) {logger.error ("HandlerInterceptor.afterCompletion threw exception", ex2);}

From the above code, we know that the afterCompletion method of the interceptor is executed in reverse.

3.3 execution of the target method

If all the preHandle methods of the interceptor above return true, then instead of directly return within the doDispatch method, the target method continues to execute. If the preHandle method of any interceptor returns false, then after executing the afterCompletion method of the interceptor (the interceptor that has already executed the preHandle method), it will directly return within the doDispatch method, and the target method will not be executed.

Execute the target method through the following code

/ / Actually invoke the handler.mv = ha.handle (processedRequest, response, mappedHandler.getHandler ())

Do not look at the specific implementation of the internal, look at the logic after the implementation.

3.4 execute the postHandle method of the interceptor

After the target method is executed, the code goes down

MappedHandler.applyPostHandle (processedRequest, response, mv)

View the logic of applyPostHandle

/ * Apply postHandle methods of registered interceptors. * / void applyPostHandle (HttpServletRequest request, HttpServletResponse response, @ Nullable ModelAndView mv) throws Exception {/ / reverse traversing for (int I = this.interceptorList.size ()-1; I > = 0; iMub -) {HandlerInterceptor interceptor = this.interceptorList.get (I); / / execute the postHandle method interceptor.postHandle (request, response, this.handler, mv) of the current interceptor;}}

PostHandle method of reverse order execution interceptor

3.5 execute the afterCompletion method of the interceptor

Keep going down.

ProcessDispatchResult (processedRequest, response, mappedHandler, mv, dispatchException)

Enter the method, which processes the execution result, renders the page, and at the end of the method executes the following code

3.6 exception handling

If an exception is thrown during the execution of the doDispatch method, the execution of the afterCompletion method will be triggered in the catch module

Read here, this "SpringBoot interceptor source code analysis" article has been introduced, want to master the knowledge of this article also need to practice and use to understand, if you want to know more about the article, welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report