Spring AOP = 责任链模式 + 代理模式

这里就不扯什么是AOP以及AspectJ的历史了,在一般大众的认知中,AOP就是在方法的前后做一些事情(Spring默认也就是方法级别的AOP)。接下来,让我们一步步实现AOP。

这是一个很普通的方法UserService#sayHello。

如何在sayHello前后做一些事情呢?最粗暴的做法是:

但这并不符合开闭原则,也不通用。如果需要在OrderService#order方法前后也做一些事情,就要把代码拷贝一份。

所以,我们必须将sayHello和sayHello前后要做的事情进行分离,而分离的目的是为了下次更好的相聚(组合)。

Spring AOP的做法是,抽象出以下概念:

  • Pointcut
  • Advice
  • Advisor

Pointcut俗称切点,可以简单理解为"怎么切/切哪里",也就是一个匹配规则,比如我们常见的AspectJExpressionPointcut,允许我们配置切点表达式:

execution(* com.bravo.test.service.UserService.sayHello(..))

Advice则是具体的增强逻辑,即前面说的"方法前后要做的事情"。

而Advisor=Pointcut+Advice。

对于符合Pointcut规则的目标方法应用Advice,在目标方法前后做一些事情。

尽管在我看来这些概念已经很清晰,但对于初学者来说还是有点绕。所以,这里再做一步简化,只留下Advice的概念,丢弃Pointcut和Advisor。没有Pointcut怎么知道哪些方法需要增强呢?交给调用者手动组装。比如:

当然,Spring内部有一个匹配过程,代码大致如下(这里不是Spring的源码):

Advisor持有Pointcut,方法匹配成功,则返回advice用于增强

讲到这,对于如何实现AOP应该有一个模糊的概念了。

接下来我们讨论最难的两个问题:

  • 如何把advice嵌入目标方法前后
  • 如何链式执行advice

在这里,Spring又抽象出了一个新的概念:MethodInvocation。

这是啥?Spring很清楚,所谓AOP,就是在调用目标方法前后额外执行一些内容。Java的反射已经封装好Method这个类,所以整个过程就是:

那我能不能把这个过程也封装一下呢?我把"Method执行前后需要额外做一些操作"这个过程抽象成MethodInvocation(方法执行)。

里面只定义一个方法proceed,表示执行方法,而且执行的时候要自动把advice也执行掉。

然后,配套的还有MethodInterceptor:

这又是啥?通俗讲就是方法拦截器,在执行方法前做些事情。在Spring中MethodInterceptor继承自Advice,大家直接看成Advice即可。

所以,现在变成了这样:

把经过Interceptor执行Method的这个过程封装成MethodInvocation

接着,我们使用JDK动态代理为userService生成代理对象。代理对象会将一次方法调用委托到目标对象,但在此之前会执行advice:

那么,如何产生链式调用呢?

MethodInvocation就是Filter模式中的FilterChain,持有Interceptor并且负责推进下一个Interceptor

具体代码放在gitee了:

gitee.com/bravo1988/d...

相关推荐
笃励14 分钟前
Java面试题二
java·开发语言·python
Leanfeng_K32 分钟前
【报错】mac m1 gateway 报错
spring·macos·spring cloud·gateway·报错
易雪寒32 分钟前
IDEA在git提交时添加忽略文件
java·git·intellij-idea
打码人的日常分享1 小时前
企业人力资源管理,人事档案管理,绩效考核,五险一金,招聘培训,薪酬管理一体化管理系统(源码)
java·数据库·python·需求分析·规格说明书
27669582921 小时前
京东e卡滑块 分析
java·javascript·python·node.js·go·滑块·京东
爱写代码的刚子1 小时前
C++知识总结
java·开发语言·c++
冷琴19961 小时前
基于java+springboot的酒店预定网站、酒店客房管理系统
java·开发语言·spring boot
九圣残炎2 小时前
【springboot】简易模块化开发项目整合Redis
spring boot·redis·后端
daiyang123...2 小时前
IT 行业的就业情况
java
Nightselfhurt2 小时前
Spring cloud 中gateway原理
spring·spring cloud·gateway