前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解。在写完 Spring IOC 容器源码分析系列文章中的最后一篇后,没敢懈怠,趁热打铁,花了3天时间阅读了 AOP 方面的源码。开始以为 AOP 部分的源码也会比较复杂,所以原计划投入一周的时间用于阅读源码。但在我大致理清 AOP 源码逻辑后,发现没想的那么复杂,所以目前进度算是超前了。从今天(5.15)开始,我将对 AOP 部分的源码分析系列文章进行更新。包括本篇文章在内,本系列大概会有4篇文章,我将会在接下来一周时间内陆续进行更新。在本系列文章中,我将会分析 Spring AOP 是如何为 bean 筛选合适的通知器(Advisor),以及代理对象生成的过程。除此之外,还会对拦截器的调用过程进行分析。与前面的文章一样,本系列文章不会对 AOP 的 XML 配置解析过程进行分析。
下面来讲讲本篇文章的内容,在本篇文章中,我将会向大家介绍一下 AOP 的原理,以及 AOP 中的一些术语及其对应的源码。我觉得,大家在阅读 AOP 源码时,一定要弄懂这些术语和源码。不然,在阅读 AOP 源码的过程中,可能会有点晕。好了,其他的就不多说了,下面进入正题吧。
2. AOP 原理关于 AOP 的原理,想必大家都知道了。无非是通过代理模式为目标对象生产代理对象,并将横切逻辑插入到目标方法执行的前后。这样一说,本章确实没什么好说的了,毕竟原理就是这么简单。不过原理归原理,在具体的实现上,很多事情并没想象的那么简单。比如,我们需要确定是否应该为某个 bean 生成代理,如果应该的话,还要进一步确定将横切逻辑插入到哪些方法上。说到横切逻辑,这里简单介绍一下。横切逻辑其实就是通知(Advice),Spring 提供了5种通知,Spring 需要为每种通知提供相应的实现类。除了以上说的这些,在具体的实现过程中,还要考虑如何将 AOP 和 IOC 整合在一起,毕竟 IOC 是 Spring 框架的根基。除此之外,还有其他一些需要考虑的地方,这里就不一一列举了。总之 AOP 原理说起来容易,但做起来却不简单,尤其是实现一个业界认可的,久经考验的框架。所以,在随后的文章中,让我们带着对代码的敬畏之心,去学习 Spring AOP 模块的源码吧。
3. AOP 术语及相应的实现本章我来向大家介绍一下 AOP 中的一些术语,并会把这些术语对应的代码也贴出来。在介绍这些术语之前,我们先来了解一下 AOP 吧。AOP 全称是 Aspect Oriented Programming,即面向切面的编程,AOP 是一种开发理念。通过 AOP,我们可以把一些非业务逻辑的代码,比如安全检查,监控等代码从业务方法中抽取出来,以非侵入的方式与原方法进行协同。这样可以使原方法更专注于业务逻辑,代码结构会更加清晰,便于维护。
这里特别说明一下,AOP 并非是 Spring 独创,AOP 有自己的标准,也有机构在维护这个标准。Spring AOP 目前也遵循相关标准,所以别认为 AOP 是 Spring 独创的。
3.1 连接点 - Joinpoint连接点是指程序执行过程中的一些点,比如方法调用,异常处理等。在 Spring AOP 中,仅支持方法级别的连接点。上面是比较官方的说明,下面举个例子说明一下。现在我们有一个用户服务 UserService 接口,该接口定义如下:
public interface UserService { void save(User user); void update(User user); void delete(String userId); User findOne(String userId); List<User> findAll(); boolean exists(String userId); }