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

The code for

The interceptor bean

@Component public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// The handler here is usually the HandlerMethod class. You can use it to get information about the currently running class and method. Println ("login"); system.out.println ("login"); return true; } } @Component public class PermissionInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("permission"); return true; }}Copy the code

The configuration class

@Configuration public class InterceptorConfig implements WebMvcConfigurer { @Resource private LoginInterceptor loginInterceptor; @Resource private PermissionInterceptor permissionInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(permissionInterceptor).addPathPatterns("/hello/test/**"); registry.addInterceptor(loginInterceptor).addPathPatterns("/hello/demo/**"); }}Copy the code

Startup phase

BeanName fororg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfigurationThe corresponding class isWebMvcAutoConfiguration.EnableWebMvcConfiguration, which inherits its parent classDelegatingWebMvcConfigurationIn the dependency injection phase, the IoC container is addedWebMvcConfigurerClass toconfigurersVariable, and ultimately indelegatesVariable representation.This is the configuration class that must be implementedWebMvcConfigurerThe reason for the interface.

At the time of instantiation for requestMappingHandlerMapping beanName, its corresponding class is requestMappingHandlerMapping, entered the following method.

WebMvcAutoConfiguration->EnableWebMvcConfiguration->requestMappingHandlerMapping(): / / execution is the parent class requestMappingHandlerMapping () return. Super requestMappingHandlerMapping (); WebMvcConfigurationSupport->requestMappingHandlerMapping(): RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping(); mapping.setOrder(0); // Set the mapping.setInterceptors(getInterceptors()); mapping.setContentNegotiationManager(mvcContentNegotiationManager()); / / Cors, if the configuration class has rewritten addCorsMappings method, will add mapping. SetCorsConfigurations (getCorsConfigurations ()); WebMvcConfigurationSupport->getInterceptors(): InterceptorRegistry registry = new InterceptorRegistry(); // addInterceptors(registry); / / add two default interceptor registry. AddInterceptor (new ConversionServiceExposingInterceptor (mvcConversionService ())); registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider())); this.interceptors = registry.getInterceptors(); DelegatingWebMvcConfiguration->addInterceptors(): this.configurers.addInterceptors(registry); WebMvcConfigurerComposite - > addInterceptors () : / / the delegates here a blocker, is the default one is configured interceptor for (WebMvcConfigurer delegate: this.delegates) { delegate.addInterceptors(registry); }Copy the code

The delegates here. A class is the default configuration WebMvcAutoConfiguration WebMvcAutoConfigurationAdapter, its addInterceptors method is empty. The other is the configured InterceptorConfig, which adds the specified interceptors to the addInterceptors method. The default interceptors are added later. In the end is the embodiment of the requestMappingHandlerMapping interceptors variables.

Instantiate the RequestMappingHandlerMapping, after in the initialization phase, will do mapping lookup and registered.

Operation phase

Specification of processing methods and interceptors

AbstractHandlerMapping->getHandler(): Object handler = getHandlerInternal(request); HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); AbstractHandlerMapping->getHandlerExecutionChain(): for (HandlerInterceptor interceptor : this.adaptedInterceptors) { if (interceptor instanceof MappedInterceptor) { MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; // When the URL conforms to the configured interceptor incluePatterns, add // when the url conforms to excludePatterns, Don't add the if (mappedInterceptor matches (lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); }} else {chain.addInterceptor(interceptor); } } return chain;Copy the code

Object Handler = getHandlerInternal(Request) Returns different processing methods for different requests (process reference mapping matching and common handlerMapping in Servlet initialization), This object is then returned by adding a matching chain of interceptors to the chain.

Interceptor invocation

DispatcherServlet->doDispatch(): DispatcherServlet->doDispatch(): DispatcherServlet->doDispatch(): DispatcherServlet->doDispatch(): mappedHandler.applyPreHandle(processedRequest, response)) { return; }... / / call the interceptor mappedHandler postHandle method. The applyPostHandle (processedRequest, response, mv); . // Finally, regardless of success or exception capture, the interceptor's afterCompletion method is calledCopy the code

conclusion

The HandlerInterceptor has three methods that are called in different phases, but the most important one is its preHandle method. If it returns false, it does not execute interface methods.

For SpringMVC flowchart

As can be seen from the figure, the filter (Filter) and interceptors (Interceptor) The biggest difference is thisThe filter precedes the Servlet