「这是我参与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);
}
}
下图可以看到其执行顺序:
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->拦截器前置->Controller处理->拦截器后置->拦截器afterCompletion
综上,可以看到两者的区别主要是实现方式、适用范围、触发时机等方面的不同。好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊