拦截器与过滤器的区别与应用

168 阅读2分钟

「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战

1、前言

​ 在之前的依次面试中,笔者被问到了Spring中拦截器与过滤器的区别?当初回答的不是很全面,自己有时间也系统的整理总结了下。下面就为大家分享下它们的区别及使用场景。

2、拦截器

​ 拦截器是基于Java的反射(动态代理)实现的,也是AOP编程的体现,所以我们可以在请求处理前、处理后分别执行拦截器,进行业务逻辑操作。同时,拦截器可以获取Spring的上下文及IOC容器中的bean。我们可以使用拦截器来做用户的登录记录等。

//定义拦截器
@Component
public class LogInterceptor extends HandlerInterceptorAdapter {

	/**
	 * 在拦截请求被执行前进行调用,如果返回false则不会继续下面的执行 
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		System.out.println("-----------执行preHandle方法--------------");
		return true;
	}

	/**
	 * 在拦截请求被执行后进行调用 
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
		System.out.println("-----------执行postHandle方法--------------");
	}

	/**
	 * 整个请求处理完毕后的回调 
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		System.out.println("-----------执行afterCompletion方法--------------");
	}

}

//注册拦截器
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private LogInterceptor logInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(logInterceptor);
    }
}

下图可以看到其执行顺序:

interceptor-01.png

3、过滤器

​ 我们自定义的过滤器都是实现的javax.servlet.Filter,所以过滤器是依赖于web容器而存在的,也不能使用IOC容器中的bean等。

public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("-----------初始化过滤器------------");
    }
	
    //这里的FilterChain作为一个参数传入,所起过滤器是基于函数回调来执行的
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("-------执行doFilter--------");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("-------销毁filter---------");
    }
}

//注册过滤器
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Bean
    public FilterRegistrationBean testFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        TestFilter testFilter = new TestFilter();
        filterRegistrationBean.setFilter(testFilter);

        List<String> urlList = new ArrayList<>();
        urlList.add("/*");

        filterRegistrationBean.setUrlPatterns(urlList);
        return filterRegistrationBean;
    }
}

可以看到,过滤器的初始化方法会在项目启动时就执行。

filter-01.png

从下图可以看到,其执行顺序是:filter->拦截器前置->Controller处理->拦截器后置->拦截器afterCompletion

filter-02.png

综上,可以看到两者的区别主要是实现方式、适用范围、触发时机等方面的不同。好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊