filter、interceptor、aspect应如何选择

前言

小伙伴们应该据说过过滤器、拦截器、切面,印象上都可以起到截断拦截的做用,在作一些业务需求时,不知道如何选择,今天老顾就来介绍一下他们之间的区别。程序员

Filter过滤器

过滤器能够拦截到方法的请求和响应(ServletRequest request, ServletResponse response),并对请求响应作出过滤操做。web

过滤器依赖于servlet容器。在实现上,基于函数回调,它能够对几乎全部请求进行过滤,一个过滤器实例只能在容器初始化时调用一次。面试

使用过滤器的目的是用来作一些过滤操做,获取咱们想要获取的数据,好比:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。redis

话很少说,先上代码sql

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

再定义两个Controller,一个UserController,一个OrderController数据库

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

虽然Filter过滤器和Controller请求都已经定义了,但如今过滤器是不起做用的。须要把Filter配置一下,有两个方案编程

第一个方案在Filter上面加上@Component缓存

@Component
public class TimeFilter implements Filter

第二个方案配置化注册过滤器tomcat

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

第二个方案的特色就是能够细化到过滤哪些规则的URL安全

咱们来启动应用时,过滤器被初始化了,init函数被回调

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

请求http://localhost:9000/order/1

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

看看控制台的日志输出

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

请求http://localhost:9000/user/1

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

控制台日志输出

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

中止应用后,控制台输出

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

Filter随web应用的启动而启动,只初始化一次,随web应用的中止而销毁。

1.启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;

2.每一次请求时都只调用方法doFilter()进行处理

3.中止服务器时调用destroy()方法,销毁实例。

咱们再来看看doFilter方法

doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

从参数咱们看到,filter里面是可以获取到请求的参数和响应的数据;但此方法是没法知道是哪个Controller类中的哪一个方法被执行。

还有一点须要注意的是,filter中是无法使用注入的bean的,也就是没法使用@Autowired

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

上面代码注入的值为null。这是为何呢

其实Spring中,web应用启动的顺序是:listener->filter->servlet,先初始化listener,而后再来就filter的初始化,再接着才到咱们的dispathServlet的初始化,所以,当咱们须要在filter里注入一个注解的bean时,就会注入失败,由于filter初始化时,注解的bean还没初始化,无法注入。

若是必定你要使用,须要作一些处理,能够私信老顾哦

Interceptor拦截器

依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在一个方法前,调用一个方法,或者在方法后,调用一个方法。

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

在WebMvcConfigurationSupport配置一下

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

执行结果

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

咱们发现拦截器中能够获取到Controller对象

preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

object handler就是controller方法对象

HandlerMethod handlerMethod = (HandlerMethod)handler;
handlerMethod.getBean().getClass().getName(); //获取类名
handlerMethod.getMethod().getName(); //获取方法名

但咱们发现获取不到方法的参数值,这个是为何呢?在DispatcherServlet类中,方法

doDispatch(HttpServletRequest request, HttpServletResponse response)

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

applyPreHandle这个方法执行,就是执行的拦截器的preHandler方法,但这个过程当中,controller方法没有从request中获取请求参数,组装方法参数;而是在ha.handle这个方法的时候,才会组装参数

虽然无法获得方法的参数,可是能够得到IOC的bean哦。

再说明一点的是postHandler方法

postHandler方法的执行,当controller内部有异常,posthandler方法是不会执行的。

afterCompletion方法,无论controller内部是否有异常,都会执行此方法;此方法还会有个Exception ex这个参数;若是有异常,ex会有异常值;没有异常 此值为null

注意点若是controller内部有异常,但异常被@ControllerAdvice 异常统一捕获的话,ex也会为null

Aspect切片

AOP操做能够对操做进行横向的拦截,最大的优点在于他能够获取执行方法的参数,对方法进行统一的处理。常见使用日志,事务,请求参数安全验证

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

上面的代码中,咱们是能够获取方法的参数的

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

虽然切面aop能够拿到方法参数,但拿不到response,request对象。

总结

咱们这里来总结一下过滤器、拦截器、Aspect,看看区别

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

若是三者方式同时采用,那他们的执行顺序是什么呢?

filter -> interceptor -> ControllerAdvice -> aspect -> controller

返回值顺序,或异常返回顺序

controller -> aspect -> controllerAdvice -> Interceptor -> Filter

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

用一个图描述一下执行顺序

阿里二面:filter、interceptor、aspect应如何选择?不少人中招

 

小伙伴们能够根据自身业务,和上面技术的各自特色,去选择相应的技术。今天老顾就介绍到这里,谢谢!!!


---End---

最近老顾上传了微服务网关的分享课程,请你们多多支持

推荐阅读

一、学习Lambda表达式看这篇就够了,不会让你失望的哦(续篇)

二、Lambda用在哪里?几种场景?

三、为何会出现Lambda表达式,你知道吗?

四、不说“分布式事务”理论,直接上大厂阿里的解决方案,绝对实用

五、女程序员问到这个问题,让我思考了半天,Mysql的“三高”架构

六、大厂二面:CAP原则为何只能知足其中两项?而不能同时知足

七、阿里P7二面:聊聊零拷贝的原理

八、秒杀系统的核心点都在这里,快来取

九、你了解如何利用token方式实现分布式Session吗?

十、Mysql索引结构演变,为何最终会是那个结构呢?让你一看就懂

十一、一场比赛涉及到的知识,用通俗易通的方式介绍并发协调

十二、企业实战Redis全方面思考,你思考了吗?

1三、面试题:Thread的start和run的区别

1四、面试题:什么是CAS?CAS的做用以及缺点

1五、如何访问redis中的海量数据?避免事故产生

1六、如何解决Redis热点问题?以及如何发现热点?

1七、如何设计API接口,实现统一格式返回?

1八、你真的知道在生产环境下如何部署tomcat吗?

1九、分享一线互联网大厂分布式惟一ID设计 之 snowflake方案

20、分享大厂分布式惟一ID设计方案,快来围观

2一、你想了解一线大厂的分布式惟一ID生成方案吗?

2二、你知道如何处理大数据量吗?(数据拆分篇)

2三、如何永不迁移数据和避免热点? 根据服务器指标分配数据量(揭秘篇)

2四、你知道怎么分库分表吗?如何作到永不迁移数据和避免热点吗?

2五、你了解大型网站的页面静态化吗?

2六、你知道如何更新缓存吗?如何保证缓存和数据库双写一致性?

2七、你知道怎么解决DB读写分离,致使数据不一致问题吗?

2八、DB读写分离状况下,如何解决缓存和数据库不一致性问题?

2九、你真的知道怎么使用缓存吗?

30、如何利用锁,防止缓存击穿?重构思想的重要性

3一、海量订单产生的业务高峰期,如何避免消息的重复消费?

3二、你知道如何保障生产端100%消息投递成功吗?

3三、微服务下的分布式session该如何管理?

相关文章
相关标签/搜索