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

170 阅读4分钟

今天查了一下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不能,它只是单纯的切入添加操作;

以上部分内容来自简书: 作者:不知名的蛋挞 链接:www.jianshu.com/p/2d1fa2834… ———————————————— 版权声明:本文为CSDN博主「leonado_liao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/DHCliaozhen…