详解Spring 拦截器流程及多个拦截器的执行顺序

网友投稿 289 2023-01-17

详解Spring 拦截器流程及多个拦截器的执行顺序

拦截器是 Spring MVC 中的组件,它可以在进入请求方法前做一些操作,也可以在请求方法后和渲染视图后做一些事情。

拦截器的定义

SpringMVC 的拦截器只需要实现 HandlerInterceptor 接口,并进行配置即可。HandlerInterceptor 接口的定义如下:

public interface HandlDlFWjUrerInterceptor {

default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

return true;

}

default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

}

default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

}

}

在 HandlerInterceptor 中共有三个方法,每个方法的含义如下:

preHandler:进入请求方法之前执行;

postHandler:请求方法执行完成之后执行;

afterCompletion:视图渲染后执行。

拦截器的执行流程

在 preHandle 方法中,它的返回值是 boolean 类型的,它的返回值影响着请求方法,以及 postHandle 和 afterCompletion 的执行。具体如下。

也就是说,在 preHandle 中如果返回 false,那么后续的流程将不被执行,这可能也是拦截器命名的由来。

测试拦截器

写一个简单拦截器,代码如下:

@Slf4j

public class TestInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

log.info("preHandler");

return true;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

log.info("postHandler");

}

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

log.info("afterCompletion");

}

}

        创建了一个 TestInterceptor 的监听器类,它实现了 HandlerInterceptor 的所有接口。写完 TestInterceptor 还需要进行注册。代码如下:

@Configuration

public class InterceptorConfig implements WebMvcConfigurer {

@Override

public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(testInterceptor());

}

再来写一个简单的请求方法,代码如下:

@GetMapping("test")

public String test()

{

return "test";

}

来启动我们的项目,并进行访问,控制台的输出如下:

2021-05-05 16:02:08.110 INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor : preHandler

2021-05-05 16:02:08.111 INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestIDlFWjUrnterceptor : postHandler

2021-05-05 16:02:08.111 INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor : afterCompletion

多个拦截器的执行顺序

我们来写多个相同的监听器,分别是 TestInterceptor、TestInterceptor2 和 TestInterceptor3。然后我们进行注册,注册代码如下:

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(testInterceptor());

registry.addInterceptor(testInterceptor2());

registry.addInterceptor(testInterceptor3());

}

请求我们的方法,输出如下:

2021-05-05 16:09:57.735 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : preHandler

2021-05-05 16:09:57.736 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : preHandler2

2021-05-05 16:09:57.736 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3 : preHandler3

2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3 : postHandler3

2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : postHandler2

2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : postHandler

2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3 : afterCompletion3

2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : afterCompletion2

2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : afterCompletion

注意观察输出的顺序,preHandle 方法是按注册顺序进行执行的,而 postHandle 和 afterCompletion 跟注册顺序是相反的。

让 preHandle 进行拦截

我们让 TestInterceptor2 的 preHandle 返回值为 false,然后查看一下输出内容。

2021-05-05 16:14:00.997 INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : preHandler

2021-05-05 16:14:00.998 INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : preHandler2

2021-05-05 16:14:00.998 INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : afterCompletion

可以看到,TestInterceptor2 的 preHandle 的返回值为 false 以后,相当于在 TestInterceptor2 的 preHandle 后续流程则不再继续执行了。

我们调整一下注册的顺序,代码如下:

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(testInterceptor2());

registry.addInterceptor(testInterceptor());

registry.addInterceptor(testInterceptor3());

}

修改顺序后的输出如下:

2021-05-05 16:17:23.956 INFO 88589 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : preHandler2

可以看到它后面的流程都被拦截了,没有机会执行了。

总结

拦截器是使用一个 List 进行保存,我们可以在项目中添加多个拦截器来完成不同的功能,比如可以进行 Token 的验证,权限的获取等。我们可以放到不同的拦截器中来进行相关的操作。

以上就是详解Spring 拦截器流程及多个拦截器的执行顺序的详细内容,更多关于Spring 拦截器的资料请关注我们其它相关文章!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:华为技术专家讲解JVM内存模型(收藏)
下一篇:Java设计模式之抽象工厂模式详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~