spring中过滤器filter、拦截器interceptor和切面aop的基本工作原理里和执行顺序

今天查了一下spirng中三种action前处理业务的三种方法过滤器、拦截器和切面的执行顺序记录一下。

三者的区别:

1、过滤器filter

过滤器是服务端的一个组件,是基于servlet实现从客户端访问服务端web资源的一种拦截机制,对请求request和响应response都进行过滤,依赖于serverlet容器,使用时,实现Filter接口,在web.xml里配置对应的class还有mapping-url

filter里面初始方法为3个,init()、doFilter()、destroy()。三个方法分别为对拦截数据进行预处理的初始化方法、实际进行业务处理的doFilter方法、和销毁方法destroy。

业务流程图如下:

 

2、拦截器interceptor

拦截器,顾名思义,它的作用就是拦截,这个要和过滤器区分开,过滤器依赖serverlet容器,获取request和response处理,是基于函数回调(框架本身调用的,它会遍历所有注册的过滤器,并且一一调用doFilter()),简单说就是“去取你想取的”。

拦截器是通过Java反射机制来拦截web请求,是“拒你想拒绝的”,它只拦截web请求,但不拦截静态资源。

拦截器,在AOP中用于在某个方法或字段被访问之前,进行拦截,然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。

@Component
public class TimeInterceptor implements HandlerInterceptor {

    // 在controller调用之前调用,通过返回true或者false决定是否进入Controller层
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("preHandle");
        System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
        System.out.println(((HandlerMethod)handler).getMethod().getName());
        request.setAttribute("startTime", new Date().getTime());
        return true;
    }
 
    // 在请求进入控制层之后调用,但是在处理请求抛出异常时不会调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
        Long start = (Long)request.getAttribute("startTime");
        System.out.println("time interceptor 耗时:"+ (new Date().getTime() - start));
    }
 
    // 在请求处理完成之后,也就是在DispatherServlet渲染了视图之后执行,也就是说这个方法必定是执行,包含异常信息,它的主要作用就是清理资源
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("afterCompletion");
        Long start = (Long) request.getAttribute("startTime");
        System.out.println("time interceptor 耗时:"+ (new Date().getTime() - start));
        System.out.println("ex is "+ex);
    }
 
}

流程图如下图所示:

 

3、aop切面

相比过滤器,拦截器能够知道用户发出的请求最终被哪个控制器处理,但是拦截器还有一个明显的不足,即不能够获取request的参数以及控制器处理之后的response。

(注意 ,只能通过request.getParameter(..)来获取)所以就有了切片的用武之地了。

@Aspect
@Component
public class TimeAspect {

    @Around("execution(* com.wtzhou.security.controller.UserController.*(..))")
//    @After("")
//    @Before("")
//    @AfterThrowing()
//    @AfterReturning()
    public Object handlerControllerMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        for (Object arg : args) {
            out.println("请求参数为:"+arg);
        }
        out.println("TimeAspect 切片开始执行");
        long start = currentTimeMillis();
        Object proceed = proceedingJoinPoint.proceed();
        out.println("切片执行耗时:" + (currentTimeMillis() - start));
        out.println("切片执行结束!");
        return proceed;
    }
}

总结

【Filter与Interceptor的区别】

  • filter基于filter接口中的doFilter回调函数,interceptor则基于Java本身的反射机制;
  • filter是依赖于servlet容器的,没有servlet容器就无法回调doFilter方法,而interceptor与servlet无关;
  • filter的过滤范围比interceptor大,filter除了过滤请求外通过通配符可以保护页面、图片、文件等,而interceptor只能过滤请求,只对action起作用,在action之前开始,在action完成后结束(如被拦截,不执行action);
  • 在action的生命周期中,拦截器可以被多次调用,而过滤器只能在容器初始化时被调用一次。

【Interceptor 与spring AOP的区别】

  • spring Interceptor也是一种aop思想,文中的spring AOP主要是讲aop应用,interceptor 的使用场合比aop小很多,顾名思义,它是拦截一些action请求,但是比aop使用起来简便;
  • 程序执行的顺序是先进过滤器,再进拦截器,最后进切面
  • Interceptor可以阻止代码执行下去,当preHandle返回false,那么这个请求就到此结束,真正的被拦截了,但是aop不能,它只是单纯的切入添加操作


以上部分内容来自简书:
作者:不知名的蛋挞
链接:https://www.jianshu.com/p/2d1fa2834d9c

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值