Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor

Basic concept

Application scenarios of interceptors

  1. Log: Records request information logs for information monitoring, statistics, and PV calculation.
  2. Permission check: for example, login check
  1. Performance monitoring: Calculate the time difference between receiving requests and finishing the execution, so as to obtain the processing time of requests; Of course, you can also delegate records in the direction (if any)
  2. Common behavior: Read cookies, tokens, etc

The difference between interceptors and filters

  1. Interceptors are based on Java’s reflection mechanism, while filters are based on function callbacks.
  2. Interceptors do not depend on the servlet container, and filters do.
  1. Interceptors work only on ACTION requests, while filters work on almost all requests.
  2. Interceptors can access the ACTION context, objects in the value stack, but filters cannot.
  1. Interceptors can be called multiple times during the life of an ACTION, while filters can only be called once when the container is initialized.
  2. The interceptor can fetch individual beans from the IOC container, but the filter can’t. This is important. Inject a Service into the interceptor to invoke the business logic

Application scenarios

  1. User login and authentication
  2. Interface Performance Record
  1. Anti-duplicate submission

Rapid application in projects

Using interceptors in SpringBoot is relatively simple, with two main steps:

  1. The HanderInterceptor interface creates an interceptor. 2. Implement the webMvcConfigurer interface to configure the interceptor

Here’s an example:

Define a HandlerInterceptor interceptor

@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("Before entering,preHandle()");
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        log.info("After the call is executed,postHandle()");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        log.info("AfterCompletion () after completing the processing logic"); }}Copy the code

2. Implement the Intgerceptor interface to configure interceptors

Different versions in SpringBoot, slightly different

The WebMvcConfigurerAdapter class is inherited from SpringBoot2.0. There are two alternatives to the WebMvcConfigurerAdapter class:

1, WebMvcConfigurationSupport inheritance

2. Implement WebMvcConfigurer

But inherit WebMvcConfigurationSupport may make the Spring – the boot failure automatic configuration of MVC. Choose according to the project situation. Now most of the before and after the project is the end of the separation, there is no demand for static resources are automatically configured so inheritance WebMvcConfigurationSupport also have not cannot.

The implementation of integrated WebMvcConfigurationSupport

@Configuration
public class MyWebConfig extends WebMvcConfigurationSupport {

    @Autowired
    MyInterceptor myInterceptor;

    public void addInterceptors(InterceptorRegistry registry) {
        /** Path to intercept **/
        String[] paths = {"/index"."/index/*"};
        /** Path that does not need to be intercepted **/
        String[] excludePathPatterns = {};
        registry.addInterceptor(myInterceptor).addPathPatterns(paths)
                .excludePathPatterns(excludePathPatterns);
        // Create a chain of interceptors}}Copy the code

The way to implement WebMvcConfigurer

@Configuration
@Slf4j
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    TimeInterceptor timeInterceptor;

    public void addInterceptors(InterceptorRegistry registry) {
        String[] paths = {"/ * *"};
        String[] excludePaths={"/login"."/info"}; registry.addInterceptor(timeInterceptor).addPathPatterns(paths) .excludePathPatterns(); }}Copy the code

Here we need to focus on details, if the above two implementations exist, there is a priority relationship; When WebMvcConfigurationSupport WebMvcConfigurer implementation classes exist at the same time, WebMvcConfigurationSupport eventually take effect, and WebMvcConfigurer won’t take effect, See WebMvcAutoConfiguration, the WebMvc auto-configuration class in Spring.

@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {}Copy the code

Introduction to the source code

Above, we can look at Spring source code. See the spring – webmvc package org. Springframework. Web. Servlet. DispatcherServlet; doDispatch()

Preprocessing method calls

Post-processing method calls

Complete the call to the processing logic

Through the above code call, you can also view the source code implementation logic. Through analysis, it can be concluded that the method execution sequence in the Springboot interceptor is preHander ->Controller- >postHandle ->afterCompletion; The latter method is executed only if preHandle returns true (you can look directly at the Spring source here).