过滤器(Filter)、拦截器(Interceptor)、切面(Aspect)的区别

1.Filter

        Filter过滤器是服务端的一个组件,是基于servlet实现从客户端访问服务端web资源的一种拦截机制,对请求request和响应response都进行过滤,依赖于serverlet容器。用时,实现Filter接口,在web.xml里配置对应的class还有mapping-url,springboot工程可以通FilterRegisteration配置后,设置要过滤的URL,特别注意:两种方式过滤器都是有序的,谁在前就先调用谁。

定义过滤器后会重写三个方法,分别是init(),doFilter(),和destory()

(1).void init(FilterConfig config)

        用于完成Filter的初始化。

(2).void destory()

        用于Filter销毁前,完成某些资源的回收。

(3).void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)

        实现过滤功能,即对每个请求及响应增加的额外的预处理和后处理。,执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理。

@Component
public class TestFilter implements Filter {

    private Logger log = LoggerFactory.getLogger(TestFilter.class);

    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("进入TestFilter过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain)
            throws IOException, ServletException {
        // 请求放行
        filterChain.doFilter(servletRequest, servletResponse);
        log.info("进入TestFilter过滤器");
    }

    @Override
    public void destroy() {
        log.info("进入TestFilter过滤器destroy销毁");
    }
}

2.Interceptor

        拦截器,顾名思义,他的作用就是拦截,这个要和过滤器区分开,过滤器依赖serverlet容器,获取request和response处理,是基于函数回调,简单说就是“去取你想取的”,拦截器是通过java反射机制,动态代理来拦截web请求,是“拒你想拒绝的”,他只拦截web请求,但不拦截静态资源,Struts2里面就是将拦截器串联,实现对请求的处理

@Component
public class TestInterceptor implements HandlerInterceptor {

    private static Logger logger = LoggerFactory.getLogger(TestInterceptor.class);

    /**
     * 这个方法是在controller调用之前调用,通过返回true或者false决定是否进入Controller层
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) {
        try {
            logger.info("进入TestInterceptor拦截器");
            return true;
        } catch (Exception e) {

        }
        return true;
    }

    /**
     * 在请求进入控制层之后调用,但是在处理请求抛出异常时不会调用
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           @Nullable ModelAndView modelAndView) throws Exception {
    }

    /**
     * 在请求处理完成之后,也就是在DispatherServlet渲染了视图之后执行,也就是说这个方法必定是执行,
     * 包含异常信息,它的主要作用就是清理资源
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                @Nullable Exception ex) throws Exception {
    }
}

再看一下springBoot里面的配置,实现WebMvcConfigurer 接口,重写addInterceptors方法,再调用register方法添加拦截器,前提,自定义的interceptor要加上spring注解被spring容器管理

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**");
    }
}

 总结,拦截器和过滤器的顺序

3.Aspect

        在使用过滤器的时能获取request和response对象,对请求和响应进行处理,使用拦截器时,我们可以通过handler来获取当前请求控制器的方法名称。

切片编程,在网上看到了一个很贴切的说法,面对的是处理过程中的方法或者阶段,以获得各部分的低耦合性的隔离效果,它是基于动态代理,它关注的是行为和过程

@Aspect
@Component
public class TestAspect {

    private Logger log = LoggerFactory.getLogger(TestAspect.class);

    @Around("execution(public * com.ipark.*.modular.*.controller.*Controller.*(..))")
    public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("进入TestAspect切面");
        Class<?> classTarget = joinPoint.getTarget().getClass();
        Class<?>[] par = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
        Object proceed = null;
        return null;
    }
}

总结,在代码里面将过滤器,拦截器,切片,还有我们常用的@ControllerAdvice异常拦截机制注解放开时,我们来看看控制台的输出

如下图

其实,当收到请求响应时,执行的顺序为filter--》interceptor--》ControllerAdvice--》Aspect,然后到达控制层,如果控制层抛出异常,最先也会被Aspect捕获,如果未处理,会继续向上一层抛出,如果到Filter也没有处理的话,就会抛到容器内部 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值