AOP是什么
AOP全称aspect-oriented programming,与OOP是同一层级的概念,是一种编程范式,目的是通过横切关注点的分离来提高程序的模块化。这句话乍一看有点 不知所谓,仔细再看,其实AOP就是为了提升程序的模块化,分离横切关注点是它的手段。
什么叫横切关注点(Cross-cutting concern)呢?这个问题不太好回答。举个例子,在实际开发中,大家很可能会调用很多个RPC服务, 对于每个RPC服务的调用我们会关注它的耗时、入参和返回值,记录下日志以便分析问题。用传统的方式实现我们需要在每个RPC调用的地方记录数据并打印日志, 这样就会导致大量重复代码。在一个应用中,如果一个功能有很多地方要使用到,比如我们刚才说的记录日志,也比如 安全、事务管理、缓存等,而这些功能无法通过传统的设计或实现从系统中分离出来,这样的功能就叫做横切关注点。
那么横切关注点怎么分离,从哪里分离呢?AOP是将横切关注点从我们的核心业务逻辑中分离出来,而在了解怎么分离之前,我们先了解一下AOP的一些术语:
- Aspect:切面,是AOP的模块化单位,类同于Class对OOP的意义。在Spring中,Aspect是一个标准的class,Spring提供两种机制将其定义为Aspect:
-
通过XML配置。
<aop:config> <aop:aspect id="myAspect" ref="aBean"> ... </aop:aspect> </aop:config> <bean id="aBean" class="..."> ... </bean>
-
通过@Aspect注解。
package org.xyz; import org.aspectj.lang.annotation.Aspect; @Aspect public class NotVeryUsefulAspect { }
-
- Join point: 连接点,是程序执行中的特定的点,Aspect从这个点插入。可以作为Join Point的有:
- 字段:AspectJ和JBoss支持。
- 构造器:AspectJ和JBoss支持。
- 方法:AspectJ、JBoss、Spring都支持。
- Advice:通知,是Aspect在Join Point上执行的动作,可以理解为Advice=要插入执行的代码 +
什么时候插入,即定义了Aspect的what和when。Spring支持以下五种Advice:
- Before
- After
- After-returning
- After-throwing
- Around
- Pointcut:切入点,也就是Advice要插入的地方,即定义了Aspect的where。它与Join Point是一对一或一对多的关系,可以理解为Pointcut是Join Point的一个子集,Pointcut会定义一个规则,匹配上这个规则的Join Point(s) 的集合即为PointCut。Aspect=Advice + Pointcut。 Spring默认使用AspectJ的切点表达式语言来定义Pointcut。
- Weaving:织入,是一个在特定Join Point将Aspect应用到目标对象,生成目标对象的代理对象的过程。Weaving一般发生在目标对象生命周期的以下几个时间点:
- Compile time:编译时,AspectJ支持这种方式,需要提供特殊的编译器。
- ClassLoad time:类加载时期,需要特定的类加载器(ClassLoader),AspectJ 5的LTW(load-time weaving)支持这种方式。
- Runtime:运行时,AOP容器动态生成一个代理对象来代理目标对象(动态代理技术),Spring目前使用这种方式。
参考资料:
- Aspect-oriented_programming
- Cross-cutting concern
- Aspect Oriented Programming with Spring
- 《Spring in Action, Third Edition》