过滤器,拦截器,aop之间差异

过滤器,拦截器,AOP之间差异

一、引言

在Spring Boot项目中,我们经常会使用到过滤器、拦截器和AOP,来实现一个切面的功能,那么他们之间的差异有哪些,在某个场景下我们应该选择哪个去使用呢?

二、客户端请求流程

当客户端发送一个请求时,执行流程如下:

  1. 客户端发送请求。
  2. 请求首先经过过滤器链中的过滤器。每个过滤器可以在doFilter方法中对请求进行处理,然后调用chain.doFilter方法继续执行下一个过滤器或目标资源。
  3. 经过过滤器处理后,请求进入拦截器。拦截器可以在请求处理之前或之后执行一些逻辑,例如验证用户权限、记录日志等。
  4. 经过拦截器处理后,请求进入AOP切面。AOP切面中的通知定义了在何时、何地执行额外的代码,例如在方法执行前后、抛出异常时等。
  5. 最终请求到达Controller方法,AOP切面的通知在方法执行前后执行额外的代码。
  6. Controller方法处理请求并生成响应。
  7. 响应经过AOP切面的通知,拦截器和过滤器,每个组件都可以在处理过程中对响应进行处理。
  8. 最终响应返回给客户端。

image-20231129200551108

接下来,我们来分别讲一下过滤器、拦截器和AOP。

三、过滤器

  1. 简介

    过滤器(Filter)是Servlet规范中的一种组件,它可以拦截客户端请求和目标资源的响应,对它们进行处理和过滤。过滤器可以用于在请求处理之前或响应返回之前执行一些逻辑,例如验证用户权限、记录请求日志、对请求进行安全过滤、设置编码、过滤敏感词汇等。

  2. 代码实现

    定义过滤器,实现Filter接口重写过滤方法

    @Component
    public class MyFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            // 过滤器初始化逻辑
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            // 在请求处理之前执行的逻辑
            System.out.println("请求前的过滤");
    
            // 调用链中的下一个过滤器,如果没有则执行目标资源
            filterChain.doFilter(servletRequest, servletResponse);
    
            // 在请求处理之后执行的逻辑
            System.out.println("请求后的过滤");
        }
    
        @Override
        public void destroy() {
            // 过滤器销毁逻辑
            Filter.super.destroy();
        }
    }
    

    定义一个Controller方法

    @RestController
    @RequestMapping("/api/activity")
    public class MyController {
        @GetMapping("/request")
        public R request() {
            System.out.println("执行了一个请求");
            return R.ok("执行了一个请求");
        }
    }
    

    测试请求结果

    image-20231129202830833

四、拦截器

  1. 简介

    拦截器(Interceptor)是Spring MVC框架提供的一种机制,用于在请求处理的不同阶段执行额外的逻辑。拦截器可以在请求处理前、请求处理后以及请求处理异常时执行一些操作,例如日志记录、权限验证、性能监控等。拦截器可以灵活地应用于Spring MVC框架中,对请求进行拦截和处理。

  2. 拦截器与过滤器的区别

    • 拦截器是AOP思想的具体应用(一个横切面,直接切进请求响应中去)。
    • 拦截器是spring MVC特有的。
    • 拦截器只会拦截访问控制器的方法,如果访问静态资源如:.jsp/html/css/image/js 时,它不会去拦截,而Filter过滤器无论什么都会去拦截。
  3. 代码实现

    定义一个拦截器,实现HandlerInterceptor接口中的拦截方法

    public class MyInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 在请求处理之前执行的逻辑
            System.out.println("请求前的拦截");
            return HandlerInterceptor.super.preHandle(request, response, handler);
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            // 在请求处理之后,视图被渲染之前执行的逻辑
            System.out.println("请求后渲染前的拦截");
            HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            // 在请求处理完成之后执行的逻辑
            System.out.println("请求后的拦截");
            HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        }
    }
    

    编写配置类,实现WebMvcConfigurer接口中的添加拦截器addInterceptors方法

    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer {
    
        @Bean
        public MyInterceptor myInterceptor() {
            return new MyInterceptor();
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(myInterceptor())
                    .addPathPatterns("/api/**")             //拦截所有api请求
                    .excludePathPatterns("/api/user/login");//放行其中的login
        }
    }
    

    Controller方法还是原来那个

    @RestController
    @RequestMapping("/api/activity")
    public class MyController {
        @GetMapping("/request")
        public R request() {
            System.out.println("执行了一个请求");
            return R.ok("执行了一个请求");
        }
    }
    

    测试请求结果

    image-20231129211845932

五、AOP

  1. 简介

    AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,它的目的是通过将横切关注点(cross-cutting concerns)从核心业务逻辑中分离出来,使得这些关注点可以被模块化、重用和集中化管理。AOP可以帮助我们实现日志记录、事务管理、安全控制、性能统计等功能,而无需修改核心业务逻辑的代码。在Java领域,Spring框架提供了强大的AOP支持。

  2. AOP的核心概念

    • 切面(Aspect):切面是横切关注点的模块化,它包含了一组通知(advice)和切点(pointcut)。通知定义了在何时、何地执行额外的逻辑,而切点定义了在何处执行额外的逻辑。
    • 通知(Advice):通知是在切面的特定连接点(join point)上执行的额外的逻辑。通知的类型包括前置通知(before advice)、后置通知(after advice)、返回通知(after-returning advice)、异常通知(after-throwing advice)和环绕通知(around advice)。
    • 连接点(Join Point):连接点是在应用执行过程中能够插入切面的点,比如方法的调用、异常的抛出等。
    • 切点(Pointcut):切点是连接点的集合,它定义了切面在何处执行额外的逻辑。切点使用表达式来匹配连接点。
    • 引入(Introduction):引入允许我们向现有的类添加新的方法或属性。
  3. 代码实现

    定义切面,定义前需要导入spring-boot-starter-aop依赖

    @Aspect
    @Component
    public class MyAop {
        @Before("execution(public * com.wnhz.ssc.*.controller.*.*(..))")
        public void before() {
            System.out.println("aop切面before");
        }
    
        @After("execution(public * com.wnhz.ssc.*.controller.*.*(..))")
        public void after() {
            System.out.println("aop切面after");
        }
    
        @AfterReturning("execution(public * com.wnhz.ssc.*.controller.*.*(..))")
        public void afterReturning() {
            System.out.println("aop切面afterReturning");
        }
    
        @AfterThrowing("execution(public * com.wnhz.ssc.*.controller.*.*(..))")
        public void afterThrowing() {
            System.out.println("aop切面afterThrowing");
        }
        
        /*@Around("execution(public * com.wnhz.ssc.*.controller.*.*(..))")
        public Object around(ProceedingJoinPoint proceedingJoinPoint) {
            Object obj;
            System.out.println("around before");
            try {
                obj = proceedingJoinPoint.proceed();
                System.out.println("around after returning");
            } catch (Throwable e) {
                System.out.println("around after throwing");
                throw new RuntimeException(e);
            } finally {
                System.out.println("around after");
            }
            return obj;
        }*/
    }
    

    Controller方法还是原来那个

    @RestController
    @RequestMapping("/api/activity")
    public class MyController {
        @GetMapping("/request")
        public R request() {
            System.out.println("执行了一个请求");
            return R.ok("执行了一个请求");
        }
    }
    

    测试请求结果

    image-20231129214239147

    这样的话,我们就验证了刚开始给出的客户端请求流程里三者之间执行的顺序了:

    用户请求——>过滤器——>拦截器——>aop切面——>Controller方法——>aop切面——>拦截器——>过滤器——>返回给用户

六、过滤器,拦截器,AOP之间差异小结

  1. 运行环境:

    • 过滤器(Filter):基于Servlet规范,作用于Servlet容器中的请求和响应。
    • 拦截器(Interceptor):基于Spring MVC框架,作用于Spring MVC中的请求和响应。
    • AOP(Aspect Oriented Programming):基于Spring框架,作用于整个应用程序中的对象或方法。
  2. 作用对象

    • 过滤器(Filter):Filter过滤器不只是拦截访问控制器的方法,还可以拦截静态资源

    • 拦截器(Interceptor):拦截器只会拦截访问控制器的方法,如果访问静态资源如:.jsp/html/css/image/js 时,它不会去拦截

    • AOP(Aspect Oriented Programming):作用对象更加抽象和广泛,不仅局限于拦截请求和访问静态资源,而是通过在连接点上执行额外的逻辑,实现对横切关注点的模块化和重用。

  3. 触发时机:

    • 过滤器(Filter):在请求进入容器之前和响应返回客户端之前执行。
    • 拦截器(Interceptor):在请求处理之前和之后执行。
    • AOP(Aspect Oriented Programming):在方法调用前、后或异常时执行。
  4. 使用场景:

    • 过滤器(Filter):适用于对请求和响应进行过滤、处理和转换,如字符编码、安全过滤、日志记录等。
    • 拦截器(Interceptor):适用于在请求处理前、后和完成后进行拦截和处理,如权限验证、性能统计、日志记录等。
    • AOP(Aspect Oriented Programming):适用于实现横切关注点的功能,如事务管理、安全控制、日志记录等。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring拦截过滤器AOP是Spring框架中常用的三种技术,用于实现对请求的处理和控制。它们的作用和使用方式有一些不同,我会分别对它们进行简单解释。 1. 过滤器(Filter): 过滤器是Java Servlet规范提供的一种技术,用于在请求到达Servlet之前或响应返回给客户端之前拦截和处理请求。过滤器可以在Web应用的整个生命周期中起作用,对所有请求都生效。常见的应用场景包括:编码转换、身份认证、日志记录等。 2. 拦截(Interceptor): 拦截是Spring框架提供的一种技术,用于在请求到达Handler(Controller方法)之前或响应返回给客户端之前对请求进行拦截和处理。拦截只在Spring MVC中起作用,用于实现对请求的预处理和后处理。常见的应用场景包括:身份认证、权限控制、日志记录等。 3. AOP(面向切面编程): AOP是一种编程思想,也是Spring框架提供的一种技术。通过AOP,可以将与业务逻辑无关的横切关注点(如日志、事务管理等)从业务逻辑中解耦出来,以模块化的方式进行管理。在Spring中,AOP通常通过动态代理实现,可以在方法执行前、后或抛出异常时进行一些额外的处理。AOP常用于事务管理、日志记录、性能监控等方面。 总结: - 过滤器主要用于在Servlet规范中对请求进行拦截和处理。 - 拦截主要用于在Spring MVC中对请求进行拦截和处理。 - AOP主要用于将与业务逻辑无关的横切关注点进行解耦和管理。 希望以上解释能对你有所帮助!如果有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值