共计 3196 个字符,预计需要花费 8 分钟才能阅读完成。
前言
关于过滤器 Filter 和拦截器 Interceptor,大家都不会陌生,从一开始的 servelet,到 springmvc,再到现在的 springboot,都有接触到,记得刚接触的时候,会容易弄混淆,想写这篇文章做个小的总结
拦截器和过滤器的异同
-
相同点
- 都是 aop 编程思想的体现,可以在程序执行前后做一些操作,如权限操作,日志记录等
-
不同点:
- Filter 是 Servlet 规范中定义的,拦截器是 Spring 框架中的
- 触发时机不一样,过滤器是在请求进入容器后,但请求进入 servlet 之前进行预处理的
- 拦截器可以获取 IOC 容器中的各个 bean,而过滤器就不行,拦截器归 Spring 管理
Springboot 实现过滤器和拦截器
第一步:定义 Filter
@Slf4j | |
public class TestFilter implements Filter { | |
@Override | |
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) | |
throws IOException, ServletException {log.info("TestFilter filter。。。。。。。。"); | |
filterChain.doFilter(servletRequest, servletResponse); | |
} | |
} |
第二步:注入 springboot 容器当中
@Configuration | |
public class FilterConfig { | |
@Bean | |
Filter testFilter(){return new TestFilter(); | |
} | |
@Bean | |
public FilterRegistrationBean<TestFilter> filterRegistrationBean1(){FilterRegistrationBean<TestFilter> filterRegistrationBean=new FilterRegistrationBean<>(); | |
filterRegistrationBean.setFilter((TestFilter) testFilter()); | |
filterRegistrationBean.addUrlPatterns("/*"); | |
//filterRegistrationBean.setOrder(); 多个 filter 的时候 order 的数值越小 则优先级越高 | |
return filterRegistrationBean; | |
} | |
} |
第三步:定义拦截器
@Slf4j | |
@Service(value = "testInterceptor") | |
public class TestInterceptor implements HandlerInterceptor { | |
@Override | |
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("TestInterceptor preHandle...."); | |
return true; | |
} | |
@Override | |
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {log.info("TestInterceptor postHandle...."); | |
} | |
@Override | |
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {log.info("TestInterceptor afterCompletion...."); | |
} | |
} |
第四步:加入 springboot 容器
@Configuration | |
public class InterceptorConfig implements WebMvcConfigurer { | |
@Autowired | |
TestInterceptor testInterceptor; | |
@Override | |
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(testInterceptor) | |
.addPathPatterns("/api/**"); | |
} | |
} |
注意:这边用的 springboot 是 2.0.x,采取的是直接实现 WebMvcConfigurer,因为 WebMvcConfigurerAdapter 被标识了 @Deprecated,就没有继承 WebMvcConfigurerAdapter 了
/** @deprecated */ | |
@Deprecated | |
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {public WebMvcConfigurerAdapter() {}} |
第五步:还是启动之前的 controller
@RestController | |
@RequestMapping("/api/test") | |
@Slf4j | |
public class TestController {@RequestMapping(value = "/hello") | |
public String test() {log.info("test hello............."); | |
return "SUCCESS"; | |
} |
看到打印结果如下
2019-04-27/12:01:04.603||||||||^_^|[http-nio-8088-exec-1] INFO com.stone.zplxjj.filter.TestFilter 22 - TestFilter filter。。。。。。。。2019-04-27/12:01:04.612||||||||^_^|[http-nio-8088-exec-1] INFO com.stone.zplxjj.interceptor.TestInterceptor 26 - TestInterceptor preHandle.... | |
2019-04-27/12:01:04.634||||||||^_^|[http-nio-8088-exec-1] INFO com.stone.zplxjj.interceptor.TestInterceptor 32 - TestInterceptor postHandle.... | |
2019-04-27/12:01:04.634||||||||^_^|[http-nio-8088-exec-1] INFO com.stone.zplxjj.interceptor.TestInterceptor 37 - TestInterceptor afterCompletion.... |
小结
过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射,代理又分静态代理和动态代理,动态代理是拦截器的简单实现。那何时使用拦截器?何时使用过滤器?
- 如果是非 spring 项目,那么拦截器不能用,只能使用过滤器,这里说的拦截器是基于 spring 的拦截器。
- 如果是处理 controller 前后,既可以使用拦截器也可以使用过滤器,如果都使用了,注意前后顺序。
- 如果是处理 dispaterServlet 前后,只能使用过滤器。
更多文章可以关注公众号:stonezplxjj
正文完
发表至: java
2019-04-27