Springboot中拦截器的使用与源码简易理解

Springboot中拦截器的使用与源码简易理解

第一篇博文想记录一下最近在基于springboot框架开发的系统中使用频率非常高的拦截器。废话不多说,开始吧!

一、初印象

相信学习过springmvc的小伙伴都拦截器一定不陌生,对于拦截器我们要知道的几个点在于:

  1. SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
  2. 过滤器与拦截器的区别:拦截器是AOP思想的具体应用( 注意是思想!!!面试的时候不要说是SpringAop动态代理实现的,具体的实现原理后边会再交代。)
    2.1.过滤器
    a. servlet规范中的一部分,任何java web工程都可以使用。
    b.在配置文件中的url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截。
    2.2.拦截器
    a.拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
    b.拦截器只会拦截访问的控制器方法,如果访问的jsp/html/css/image/js是不会进行拦截的

二、拦截器使用

ok,再三确定了我们有使用到SpringMVC框架(我用的Springboot,包含SpringMVC了哈),那么我们开始操作。

  1. 自定义拦截器类实现HandlerInterceptor接口,按需要重写此接口中定义好的方法。分别为:preHandler()、postHandle()、afterCompletion()
    1.1以preHandler()为例,写一个简单的登录拦截逻辑:我们检查session中有没有参数loginUserName(已登录用户),如果不为空,则通过;如果为空那么往request域中添加msg参数返回给前台表单,最后俺们请求转发,再给他拦截,完事儿。
    1.2这段简单逻辑想要告诉大家的就是:HandlerInterceptor接口中的三个方法都为boolean类型,返回true时,请求通过,返回false,请求拦截
    1.3三个方法的执行顺序,其实我们通过命名就可知。至于何时执行,大家可以做个测试:在本类上添加日志注释@Slf4j,然后我们将三个方法一一重写,方法逻辑中我们log.info一下不同内容,拦截时看看他们的执行顺序即可。
//图一
 @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        log.info("preHandle拦截的请求路径是{}",requestURI);
        //登录检查逻辑
        HttpSession session = request.getSession();
        if (session.getAttribute("loginUserName") != null) {
            return true;
        }
        request.setAttribute("msg","请先登录");
        request.getRequestDispatcher("/").forward(request,response);
        return false;
    }
  1. 写一个配置类实现WebMvcConfigurer接口重写addInterceptors方法。
    2.1形参registry调用方法addInterceptor()。
    2.2其中addPathPatterns是负责拦截。excludePathPatterns是负责放行。(我们在拦截请求的同时会把静态资源也拦截掉,那我们需要使用页面样式等静态资源的时候,就无法显示了,所以此处做放行)
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
 @Override
 public void addInterceptors(InterceptorRegistry registry) {
     //"/**"是将所有请求拦截 包括静态资源
     registry.addInterceptor(new LoginInterceptor()).
             addPathPatterns("/**").//拦截
             excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");//放行
 }
}
  1. 看到这里,有没有回忆到一些以前学习的内容呢?
    -----首先@Configuration注释说明这是个配置类,他把这个类就注入到了容器中。 那我们当初学些SpringMVC的时候用配置文件,拦截器又是怎么写的呢?
    -----springmvc-servlet.xml中配置拦截器
 <!--关于拦截器的配置-->
 <mvc:interceptors>
     <mvc:interceptor>
         <mvc:mapping path="/user/**"/>
         <bean id="loginInterceptor" class="com.atouyang.interceptor.MyInterceptor"/>
     </mvc:interceptor>
 </mvc:interceptors>

三、源码理解

源码部分就不展开说,但是理解拦截器一定要搞懂HandlerInterceptor接口中方法的执行顺序。我们就将源码以文字形式描述出来。首先,我们假设我们有好几个拦截器。

  1. 顺序执行所有拦截器的 preHandle方法
    1.1如果当前拦截器prehandler返回为true。则执行下一个拦截器的preHandle
    1.2如果当前拦截器返回为false。直接倒序执行所有已经执行了的拦截器的 afterCompletion;
  2. 当preHandler方法执行完后,倒序执行postHandler方法。同上,返回true,则执行下一个postHandler,一旦出异常,倒序执行所有已经执行了的拦截器的 afterCompletion。
  3. 同理,postHandler处理完后,倒序执行 afterCompletion

注意点:前面的步骤有任何异常都会直接倒序触发 afterCompletion。页面成功渲染完成以后,也会倒序触发 afterCompletion。

流程看完是不是不太好理解呢。此处贴上一张尚硅谷雷神课堂笔记上的图,帮助大家理解。
Alt
最后,想要深入学习拦截器源码的同学,这里贴上一篇好文链接。
链接: SpringMVC拦截器源码解析.

写到这里啦!谢谢大家阅读!欢迎互相学习监督!!!
Alt

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值