品牌型号:联想ThinkPad X1
系统:Windows10家庭版
软件版本:Spring 5.3.7
Spring拦截器和Spring的AOP放在一起很容易让人犯迷糊,两个都能在方法执行前后插入业务逻辑,看起来功能一样,但实际上差别很大。用了一段时间Spring之后会发现,很多人对拦截器的认知停留在"能拦请求",对AOP的认知停留在"能做切面",至于两者边界在哪、各自适合干什么,就说不上来。下面就给大家介绍一下Spring拦截器与AOP的区别,Spring拦截器的作用的相关内容。
一、Spring拦截器与AOP的区别
我们就来先说拦截器和AOP根本的差异:拦截器是Spring MVC的东西,只作用于HTTP请求;AOP是框架层面的能力,任何Spring管理的Bean都能切。这个范围的差别,也就决定了这两个技术后面所有的不同。

拦截器能拦的只有Controller层的请求,无法介入Service层方法。AOP没这个限制,想在哪切在哪切,粒度可以细到某个具体方法,灵活得多。

实现上也走的不是一条路,拦截器是责任链,请求依次执行preHandle,响应阶段再执行postHandle与afterCompletion。AOP走的是动态代理,有接口就用JDK代理,没接口就用CGLIB代理,方法调用被代理对象接管后织入逻辑再执行原方法。

实际上我们在开发的时候选哪个,并不难判断,像登录校验、接口日志这类业务跟HTTP请求强绑定,那就用拦截器处理。而事务、性能监控这类业务需要横切多个层,跟请求实际上并没什么关系的,那就用AOP来处理。两者定位本来就不同,不存在谁替代谁,想混用其实也没多大问题。
二、Spring拦截器的作用
Spring拦截器常干的事,其实就那几类,但每一类背后都有点东西值得说的,登录校验和权限控制是我们实际开发中经常使用到的。请求进Controller之前,先在preHandle方法里检查一下token或者session,如果发现没登录的就直接拦回去,不用每个Controller方法都写一遍重复逻辑,这确实帮我们省不少事。

开发中接口日志也很常见,我们客户端请求进来记一次,响应出去再记一次,耗时、参数、返回结果全留着,排查问题的时候非常好用,这种逻辑放拦截器里统一处理,比散落在各个Controller里干净得多。

还有就是数据预处理也是一个常见的场景,比如从请求头里统一解析用户信息、租户ID之类的,存到ThreadLocal里,后续业务代码直接取,不用每个地方都手动解析一遍。
另外一个容易被忽略的点就是:拦截器的afterCompletion方法在请求完成后执行,不管中间有没有抛异常都会走到,这里就很适合做一些收尾清理工作,比如释放ThreadLocal,防止内存泄漏。

简单来说,拦截器干的事都有个共同点,都和HTTP请求强相关,并且都需要在多个接口里复用横切逻辑,我们把这些东西收拢到拦截器里,代码结构会清爽很多。
以上就是Spring拦截器与AOP的区别,Spring拦截器的作用的全部内容了。拦截器和AOP看着像,但一个管HTTP请求这条线,一个横切整个Bean体系,只是定位不同,并不存在谁比谁好。拦截器适合处理的场景很集中,我们上面提到的登录校验、接口日志、数据预处理,凡是跟请求强绑定又需要复用的逻辑,交给它就对了。