SpringBoot实现拦截器和源码分析

SpringBoot实现拦截器和源码分析

1、定义拦截器

在这里插入图片描述

  • preHandle方法实在是controller执行之前执行
  • postHandle方法是在controller执行后执行
  • afterCompletion方法在模板渲染后执行

示例:

/**
 * 登录检查
 * 1、配置好拦截器要拦截哪些请求
 * 2、把这些配置放在容器中(之前在servlet的时候,实在xml里写,拦截哪些路径)
 * 3、
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 目标方法执行之前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String requestURI = request.getRequestURI();
        log.info("拦截的请求路径是:"+requestURI);

        //登录检查
        HttpSession session = request.getSession();
        Object loginUser = session.getAttribute("loginUser");
        if (loginUser != null){
            //放行
            return true;
        }
        //拦截住,就是未登录,跳转到登录页面   /就是当前项目页的首页
        session.setAttribute("msg","请先登录");
        response.sendRedirect("/");
        return false;
    }

    /**
     * 目标方法执行完成以后
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle执行{}",modelAndView);
    }

    /**
     * 页面渲染以后
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion执行异常{}",ex);
    }
}

2、配置拦截器

@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
/**
     *     注入自定义拦截器
     */
    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加拦截器
        InterceptorRegistration interceptor = registry.addInterceptor(loginInterceptor);
        //添加 要拦截的路径 , /** 动态和静态资源 都会被拦截
        InterceptorRegistration pathPatterns = interceptor.addPathPatterns("/**");
        //添加 要放行的 路径
        InterceptorRegistration pathPatterns1 = interceptor.excludePathPatterns("/", "/login","/css/**",
                "/fonts/**","/images/**","/js/**");
    }
}

3、拦截器源码分析

在这里插入图片描述
1、找到可以处理请求的handler 以及 handler的所有拦截器, HandlerExecutionChain 处理器执行链

LoginInterceptor是我们自定义的拦截器,而下面两个Conversion…和Resource…两个拦截器任何方法都会执行

mappedHandler = getHandler(processedRequest);

2、先来顺序执行 所有拦截器的 preHandle方法

  • 1、如果当前拦截器prehandle返回为true。则执行下一个拦截器的preHandle

  • 2、如果当前拦截器返回为false。直接 倒序执行所有已经执行了的拦截器的 afterCompletion;

    (就是比如三个拦截器,前两个都放行,但是第三个没有放行,然后就会倒序执行 2-1 的afterCompletion)

源码中 for (int i = 0; i < this.interceptorList.size(); i++) ,所以是先来先服务

在这里插入图片描述

3、如果任何一个拦截器返回false。直接跳出不执行目标方法

if(!mappedHandler.applyPreHandle(processedRequest,response)){
   return;
}

4、所有拦截器都返回True。执行目标方法

5、倒序执行所有拦截器的postHandle方法。
在这里插入图片描述
6、前面的步骤有任何异常都会直接倒序触发 afterCompletion

7、页面成功渲染完成以后,也会倒序触发 afterCompletion

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值