SpringMVC拦截器链
mzz124 人气:01、拦截器链实现
只需定义多个拦截器的 bean,然后在拦截器的配置类中将其逐一添加即可
第一个拦截器的定义:
@Component public class ProjectInterceptor1 implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle111..."); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle111..."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion111..."); } }
第二个拦截器的定义:
@Component public class ProjectInterceptor2 implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle222..."); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle222..."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion222..."); } }
拦截器配置类:
@Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport { @Autowired private ProjectInterceptor1 interceptor1; @Autowired private ProjectInterceptor2 interceptor2; @Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(interceptor1).addPathPatterns("/books", "/books/*"); registry.addInterceptor(interceptor2).addPathPatterns("/books", "/books/*"); } }
2、拦截器链的执行顺序
拦截器配置类中,首先被添加的拦截器在外层,之后添加的在内层,请求发出之后首先被外层的拦截器拦截,外层放行后进入内层,而离开拦截器时先离开内层的拦截器,再离开外层。
上例子中第一个拦截器在外层,第二个在内层,所以上例中拦截器的输出顺序为:
preHandle111...
preHandle222...
postHandle222...
postHandle111...
afterCompletion222...
afterCompletion111...
值得注意的是,afterCompletion 方法的一定会在 postHandle 之后执行,并且也是由内层向外层执行,所以 afterCompletion222 输出在 postHandle111 之后,而在 afterCompletion111 之前。换言之,即便有再多的拦截器,最先执行的 afterCompletion 也一定在最后执行的 postHandle 之后才执行
此外,当拦截器的 preHandle 方法返回 false 时,其内层的拦截器以及它自身 postHandle 和 afterCompletion 都不会再执行,而所有外层拦截器的 postHandle 不再执行,但 afterCompletion 照常执行
这是因为 postHandle 执行在原始 Controller 方法执行之后,必须所有拦截器都放行时,才会执行原始方法,也就才会执行 postHandle 方法
上例中第二个拦截器 preHandle 返回 false 时的输出顺序:
preHandle111...
preHandle222...
afterCompletion111...
加载全部内容