美文网首页spring系列
基于Spring boot的拦截(Filter,Intercep

基于Spring boot的拦截(Filter,Intercep

作者: Candy_糖果 | 来源:发表于2019-07-08 23:01 被阅读0次

    问题

    1. 当客户端请求服务器接口时,我需要验证一下用户的登陆权限。接口少的时候,我可以在每个接口里验证,但当接口成百上千时,这种重复的工作就会显得很冗余
    2. 同理当客户端请求服务器接口时,我想要计算每个接口运行时花费的时间,开始时可以在代码的开始和结束计算时间,最后在返回时打印时间出来。但当接口成百上千时,这种重复的工作就会显得很冗余

    解决思路

    针对这种重复性问题,可以抽象出一层代理来解决

    1. 可以写一个抽象的类实现登陆权限验证,后边每一个Controller都继承这个抽象接口
    2. 还有框架自带的拦截,是在controller被调用前和后做的一个拦截,原理都是抽象出一层来解决这个重复性的问题

    拦截

    下面我们看看 spring boot 是怎么抽象出这层拦截

    一共有三种方式,分别是 Filter,Interceptor,AOP

    它们拦截的顺序
    Filter -> Interception -> AOP -> 具体执行的方法 -> AOP-> @ControllerAdvice 全局异常处理-> Interception-> Filter

    image.png

    它们的共同点都是拦截,下边谈谈它们的不同点和场景的使用范围

    1. Filter 不依赖于框架,依赖于Servlet容器。网上有人说不能在该类里使用bean,经过测试后,是可以的,再要在类上加 @Component就可以被spring框架扫描到。
    2. Interceptor 依赖spring框架,是 AOP 的一种实现,建议优先使用Interceptor,而不是Filter。毕竟框架封装的,接口功能会更丰富一些
    3. AOP 是spring的一大特性,它也可以起到拦截的作用,不过主要用于拦截接口,注解,可以获取接口的参数,Interceptor,Filter都不能。

    总的来说,拦截接口时,使用AOP,拦截Controller时,使用Interceptor

    代码实现

    下边我们看看它们的具体实现,很简单,就不一一解释了

    Filter 实现

    /**
     * Created jixinshi on 2019-07-08.
     */
    @Component
    @Slf4j
    public class TestFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            log.info("========= before doFilter ===========");
            chain.doFilter(request, response);
            log.info("========= after doFilter ===========");
        }
    
        @Override
        public void destroy() {
        }
    }
    

    Interceptor 实现

    /**
     * Created jixinshi on 2019-07-08.
     * 拦截器,继承 HandlerInterceptorAdapter,可以根据需求实现接口
     */
    @Component
    @Slf4j
    public class TestInterceptor extends HandlerInterceptorAdapter {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            log.info("========= preHandle ===========");
            return super.preHandle(request, response, handler);
        }
    
        @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 {
        }
    }
    
    /**
     * Created jixinshi on 2019-07-08.
     */
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Resource
        private TestInterceptor testInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(testInterceptor)
                    .addPathPatterns("/**");
        }
    }
    

    AOP 实现

    /**
     * Created jixinshi on 2019-07-08.
     */
    @Component
    @Aspect
    @Slf4j
    public class TestAspect {
    
        @Pointcut("execution(public * com.example.demo.controller.*Controller.*(..))")
        public void pointcut() {
        }
    
        @Around("pointcut()")
        public Object function(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            log.info("========= before aspect ===========");
            Object proceed = proceedingJoinPoint.proceed();
            log.info("========= after aspect ===========");
            return proceed;
        }
    
    }
    

    另外,之前写了一篇 Spring AOP 通过注解的方式 打印接口执行的时间
    请点这里

    调用接口 hello/test

    执行效果图

    image.png

    衍生问题

    拦截涉及到Spring MVC框架的前与后,既然来都来了,下篇文章就让我们思考下Controller在Spring MVC中的地位,并如何被抽象?

    写完了
    https://www.jianshu.com/p/058216e3b543

    参考

    1. SpringBoot中的拦截机制
    2. Spring:过滤器filter、拦截器interceptor、和AOP的区别与联系
    3. Spring 梳理 - filter、interceptor、aop实现与区别 -第二篇
    4. Filter,Interceptor,AOP 区别与实例

    本文是基于自己理解写的,如果有错欢迎留言讨论

    相关文章

      网友评论

        本文标题:基于Spring boot的拦截(Filter,Intercep

        本文链接:https://www.haomeiwen.com/subject/fpqmhctx.html