【SpringBoot2—Web拦截器源码解析】

源码解析

版本信息:SpringBoot 2.6.1

1. 拦截器源码解析

1.1 测试 controller 编写

@RestController
@Slf4j
public class TestController {

    @GetMapping("/user/{id}")
    public User user(@PathVariable Integer id) {
        log.info("查询用户信息id={}", id);
        User user = new User();
        user.setName("张三");
        user.setAge(18);
        return user;
    }
}

1.2 拦截器编写

自定义一个拦截器,拦截的方法中我们就简单的打印一句话

@Slf4j
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("执行preHandle....");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("执行postHandle....");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("执行afterCompletion....");
    }
}

1.3 添加拦截器

设置规则为拦截所有 /user 开头的请求

@Configuration
public class MyWebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/user/**");
    }
}

1.4 debug 源码

接下来我们用 postman 发起请求来看一下拦截器的处理过程
在这里插入图片描述

对于web请求的处理流程我们直接从 org.springframework.web.servlet.DispatcherServlet#doDispatch 开始看

再获取到请求处理器适配器之后,我们直接来到 applyPreHandle()在这里插入图片描述
顺序遍历所有的拦截器执行他们的 preHandle() 方法,如果没有放行就会执行 triggerAfterCompletion()
在这里插入图片描述
注意如果执行了triggerAfterCompletion(),内部会倒序执行每一个拦截器的 afterCompletion()
在这里插入图片描述

执行完前置处理器后接下来就是执行目标方法
在这里插入图片描述

接下来就是执行 applyPostHandle()
在这里插入图片描述
注意此时是倒序执行所有拦截器的 postHandle()
在这里插入图片描述
接下来执行 processDispatchResult() 处理请求结果
在这里插入图片描述
在这个方法中执行 triggerAfterCompletion()
在这里插入图片描述
注意这里是倒序执行所有已执行拦截器的 afterCompletion() 方法
在这里插入图片描述
如果在请求过程中出现了异常,也会执行所有已执行拦截器的 afterCompletion()
在这里插入图片描述

本次 debug 涉及的关键断点如下图所示
在这里插入图片描述

2. 总结

  1. 顺序执行所有拦截器preHandle(),返回false倒序执行已执行preHandle()的拦截器的 afterCompletion()
  2. 执行目标方法
  3. 倒序执行所有拦截器的 postHandle()
  4. 倒序执行所有拦截器的 afterCompletion()
  5. 期间出现任何异常都会倒序执行已执行preHandle()的拦截器的 afterCompletion()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值