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$EnableWebMvcConfiguration
The corresponding class isWebMvcAutoConfiguration.EnableWebMvcConfiguration
, which inherits its parent classDelegatingWebMvcConfiguration
In the dependency injection phase, the IoC container is addedWebMvcConfigurer
Class toconfigurers
Variable, and ultimately indelegates
Variable representation.This is the configuration class that must be implementedWebMvcConfigurer
The 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