过滤器跟拦截器的区别

过滤器跟拦截器的区别

1、过滤器(Filter)

过滤器的配置比较简单,直接实现 Filter 接口即可,也可以通过 @WebFilter 注解实现对特定URL 拦截, 看到Filter 接口中定义的三个方法。

1、init(); 该方法在容器启动初始化过滤器时被调用,它在Filter 的整个生命周期只会被调用一次。

2、doFilter(); 容器中的每一次请求都会调用该方法,FilterChain 用来调用下一个过滤器 Filter。

3、destroy(); 当容器销毁 过滤器实例时调用该方法,一般在方法中销毁或关闭资源,在过滤器 Filter 的整个生命周期也只会被调用一次。

 @Component
public class MyFilter implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter 前置");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter 处理中");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("Filter 后置");
    }
}

2、拦截器(Interceptor)

拦截器时链式调用,一个应用可以同时存在多个拦截器Interceptor,一个请求也可以触发多个拦截器,顺序依调用顺序依次进行。

1、preHandle(); 这个方法将在请求处理之前进行调用。 如果该方法返回值为false,将视为请求结束。

2、postHandle(); 只有在preHandle() 方法返回值为true时才会执行。会在Controller 方法请求后调用,DispatcherServlet 返回渲染视图之前被调用。

3、afterCompletion(); 在preHandle() 方法返回值为true 才会执行,在整个请求结束后, DispatcherServlet 返回渲染视图之后被调用。

@Component
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Interceptor 前置");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor 处理中");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("Interceptor 后置");
    }
}

两者都体现了AOP(面向切面编程)的编程思想。

3、两者不同之处

  • 实现原理不同

    过滤器 基于函数回调。

    拦截器 基于java的反射机制(动态代理)。

  • 使用范围不同

    过滤器: 实现 javax.servlet.Filter 接口,而这个接口实在Servlet 规范中定义的, 依赖于Tomcat 服务器。只能在 web 程序中使用。

    拦截器:spring组件,由spring管理,并不依赖于Tomcat等容器,可以单独使用。

  • 触发时机不同

    img

    ​ 过滤器(Filter):进入容器之后,在进入servlet 之前进行预处理,请求结束时在servlet 出完之后。

    ​ 拦截器(Interceptor):进入servlet 后,在进入controller 之前进行预处理。

  • 拦截的请求范围不同

  • 注入bean情况不同

    过滤器:对于服务可正常使用

    拦截器:加载的时间点在springcontext之前,Bean又是由spring进行管理。所以我们如果由需要在拦截器中使用注入的服务必须手动将Interceptor 进行注入。

    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer {
    
        @Bean
        public MyInterceptor getMyInterceptor(){
            System.out.println("注入了MyInterceptor");
            return new MyInterceptor();
        }
        
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
    
            registry.addInterceptor(getMyInterceptor()).addPathPatterns("/**");
        }
    }
    
  • 控制执行顺序不同

posted @ 2020-06-06 15:23  _不正  阅读(318)  评论(0编辑  收藏  举报