上面说了dispatcher servlet的执行流程源码,现在分析下拦截器的源码
首先看下自己的的interceptor ,然后还需要将inerceptor注册到WebMvcConfigurer中
实现
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyIntecepter implements HandlerInterceptor {
//该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;
当其返回值为false时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)。
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(request.getParameter("kang"));
System.out.println("11111");
return true;
}
//该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
System.out.println("22222");
}
//该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。 preHandle拦截返回false也会执行这个方法
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
System.out.println("3333");
}
}
package com.example.demo.config;
import com.example.demo.config.MyIntecepter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor()).addPathPatterns("/**");//将自己的拦截器注册到spring中并添加拦截的路径
}
@Bean
MyIntecepter myInterceptor(){
return new MyIntecepter();//提供自己的拦截器的bean
}
}
源码分析
interceptor拦截器是在springmvc 执行流程中执行的,看下源码:
加载所有的Interceptos
类:AbstractHandlerMapping
protected void initApplicationContext() throws BeansException {
this.extendInterceptors(this.interceptors);
//扫描拦截器
this.detectMappedInterceptors(this.adaptedInterceptors);
this.initInterceptors();
}
DispatcherServlet中 将初始化的拦截器加入hadderMapping返回的HandlerExecutionChain中
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = handler instanceof HandlerExecutionChain ? (HandlerExecutionChain)handler : new HandlerExecutionChain(handler);
Iterator var4 = this.adaptedInterceptors.iterator();
while(var4.hasNext()) {
HandlerInterceptor interceptor = (HandlerInterceptor)var4.next();
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor)interceptor;
if (mappedInterceptor.matches(request)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
} else {
chain.addInterceptor(interceptor);
}
}
DispatcherServlet中dodispatch 执行前置
//执行完前置后如果返回false,就拦截终止接下来的执行流程,直接返回
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
//执行完前置后如果返回false,就拦截终止接下来的执行流程,直接返回
if (!interceptor.preHandle(request, response, this.handler)) {
this.triggerAfterCompletion(request, response, (Exception)null);
return false;
}
}
return true;
}
DispatcherServlet中dodispatch 执行后置,是在返回modelview后执行
mappedHandler.applyPostHandle(processedRequest, response, mv);
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
for(int i = this.interceptorList.size() - 1; i >= 0; --i) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
interceptor.postHandle(request, response, this.handler, mv);
}
}
这里执行afterCompletion
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
}
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) {
for(int i = this.interceptorIndex; i >= 0; --i) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
try {
interceptor.afterCompletion(request, response, this.handler, ex);
} catch (Throwable var7) {
logger.error("HandlerInterceptor.afterCompletion threw exception", var7);
}
}
}