过滤器、拦截器、aop -> ‘三兄弟‘

文章介绍了过滤器、拦截器和AOP在Web开发中的角色和区别,强调了它们的执行顺序和使用场景。过滤器主要用于URL级别的处理,如安全过滤和字符编码设置;拦截器则更细致,能控制到方法级别,常用于权限验证和性能监控;AOP面向切面编程,可实现更复杂逻辑,如日志记录。文章提供了Spring中Filter和Interceptor的配置示例。
摘要由CSDN通过智能技术生成

目录

 

一、熟悉

 三兄弟的区别

过滤器和拦截器的区别

 使用场景

二、使用

filter

Interceptor

aop


一、熟悉

三个词都很熟悉,在某些课程或者博客中总被提到,但平时基本不怎么写;

三者在家族中的关系可以看下下边这张图,可以很直观的看到,如果一个请求过来的时候
        1、先会经过filter链,之后才会到达servlet中;

        2、然后才会到达interceptor拦截器;

        3、通过拦截器后,会被指定的aop拦截到;

        4、最后才会到达服务层;

 三兄弟的区别

        1、过滤器,拦截器拦截的是URL。AOP拦截的是类的元数据(包、类、方法名、参数等)。

        2、过滤器并没有定义业务用于执行逻辑前、后等,仅仅是请求到达就执行。

        3、拦截器有三个方法,相对于过滤器更加细致,有被拦截逻辑执行前、后等。

        4、AOP针对具体的代码,能够实现更加复杂的业务逻辑。

        三者功能类似,但各有优势,从过滤器–》拦截器–》切面,拦截规则越来越细致。 执行顺序依次是过滤器、拦截器、切面。

过滤器和拦截器的区别

        1、最简单明了的区别就是过滤器可以修改request,而拦截器不能

        2、过滤器需要在servlet容器中实现,拦截器可以适用于javaEE,javaSE等各种环境

        3、拦截器可以调用IOC容器中的各种依赖,而过滤器不能(不绝对)

        4、过滤器只能在请求的前后使用,而拦截器可以详细到每个方法

        5、过滤器和拦截器触发时机不一样,过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。

        6、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。

        7、过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射

        8、Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。

        9、Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理(反射)的方式来执行。

        10、Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。

 使用场景

        三者的功能大致相同,但根据自身特点,在使用的时候可以根据场景选择更适合的;

        过滤器:

                1、过滤敏感词汇(防止sql注入等)

                2、设置字符编码

                3、URL级别的权限访问控制

                4、压缩响应信息

        拦截器:

                1、登录验证,可以根据request中的获取用户信息等来验证是否登录;

                2、权限控制,访问目标资源之前,进行权限检查,检查用户有无权限;

                3、处理cookie、本地化、国际化、主题等

                4、性能监控,监控请求处理时长等。

        aop:

                1、日志记录,记录请求操作日志,以便统计请求访问量.(粒度更细,比拦截器更合适)

二、使用

filter

        方式1:bean方式(无法注入IOC中的bean)

/**
 * Filter是依赖于Servlet的,需要有Servlet的依赖。
 * init() 在容器初始化时执行,只执行一次。
 * doFilter() 目标请求之前拦截执行,拦截之后需要放行才开始执行目标方法。filterChain.doFilter(servletRequest,servletResponse);
 * destroy() 在容器销毁时执行,只执行一次。
 * Filter可以拦截所有请求。包括静态资源[css,js…等]。
 * 基于函数回调实现。
 * 过滤器只能在容器初始化时被调用一次。
 */
public class TestFilter2 implements Filter {

//    @Autowired
//    AsyncService asyncService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @SneakyThrows
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

//        asyncService.task(2);
        System.out.println("进入注解方式filter   bean 方式");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}
@Configuration
public class filterConfig {
    @Bean
    public FilterRegistrationBean heFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean(new TestFilter2());
        // 匹配规则
        registration.addUrlPatterns("/*");
        // 过个过滤器的执行顺序,数字越小优先级越高
        registration.setOrder(1);
        return registration;
    }

}

        方式二:注解(可以注入IOC中的bean)

@Component
// filterName就是当前类名称,还有一个urlPattens的参数,这个参数表示要过滤的URL上的后缀名,是多参数,可以用数组表示。
@WebFilter(value = "/*") // (filterName = "f1", urlPatterns = {"*.html","*.jsp","/hello"})
public class TestFilter implements Filter {

    @Autowired
    AsyncService asyncService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @SneakyThrows
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        asyncService.task(1);
        System.out.println("进入注解方式filter");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

Interceptor

@Component
public class InterceptorTest implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器preHandle在控制器方法执行前执行");
        //true:表示放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("拦截器postHandle在控制器方法执行后执行");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("拦截器afterCompletion在请求完成后执行");
    }
}
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Resource
    private InterceptorTest interceptorTest;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // ** 表示所有拦截路径
        registry.addInterceptor(interceptorTest).addPathPatterns("/**");
//        // 或下面这种写法  【若编写自定义拦截器类没有加@Component注解】
//        registry.addInterceptor(new interceptorTest()).addPathPatterns("/**");
    }
}

aop

springboot中的aop配置(hello world)及统一异常处理_springboot aop异常处理_子书少卿的博客-CSDN博客

todo:

        过滤器修改请求参数
        过滤器中注入bean的方式(有出入)
        多过滤器时(两种方式混合),默认顺序和顺序控制

                

参考资料:拦截器、过滤器、AOP的区别和联系_过滤器和aop_可爱发的博客-CSDN博客

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值