1.6 Spring AOP的原理

1.6.1 Spring AOP简介

Spring AOP通过面向切面技术将与业务无关却为业务模块所共用的逻辑代码封装起来,以提高代码的复用率,降低模块之间的耦合度。

Spring AOP将应用分为核心关注点和横切关注点两个部分。业务处理流程为核心关注点,被业务所依赖的公共部分为横切关注点。横切关注点的特点是其行为经常发生在核心关注点的多处,而多处操作基本相似,比如权限认证、日志、事务。AOP的核心思想是将核心关注点和横切关注点分离开来,以降低模块耦合度。Spring AOP的主要应用场景如表1-4所示。

表1-4 Spring AOP的主要应用场景

1.6.2 AOP的核心概念

◎横切关注点:定义对哪些方法进行拦截,拦截后执行哪些操作。

◎切面(Aspect):横切关注点的抽象。

◎连接点(Joinpoint):在Spring中,连接点指被拦截到的方法,但是从广义上来说,连接点还可以是字段或者构造器。

◎切入点(Pointcut):对连接点进行拦截的定义。

◎通知(Advice):拦截到连接点之后要执行的具体操作,通知分为前置通知、后置通知、成功通知、异常通知和环绕通知5类。

◎目标对象:代理的目标对象。

◎织入(Weave):将切面应用到目标对象并执行代理对象创建的过程。

◎引入(Introduction):在运行期为类动态地添加一些方法或字段而不用修改类的代码。

1.6.3 AOP的2种代理方式

Spring提供了JDK和CGLib 2种方式来生成代理对象,具体生成代理对象的方式由AopProxyFactory根据AdvisedSupport对象的配置来决定。Spring默认的代理对象生成策略为:如果是目标类接口,则使用JDK动态代理技术,否则使用CGLib动态代理技术。

◎JDK动态代理:JDK动态代理主要通过java.lang.reflect包中Proxy类和InvocationHandler接口来实现。InvocationHandler是一个接口,不同的实现类定义不同的横切逻辑,并通过反射机制调用目标类的代码,动态地将横切逻辑和业务逻辑编制在一起。Proxy类利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象。JDK 1.8中Proxy类的定义如下。

◎CGLib动态代理:CGLib即Code Generation Library,它是一个高性能的代码生成类库,可以在运行期间扩展Java类和实现Java接口。CGLib包的底层通过字节码处理框架ASM来实现,通过转换字节码生成新的类。

◎CGLib动态代理和JDK动态代理的区别:JDK只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,则只能通过CGLib创建动态代理来实现。

1.6.4 AOP的5种通知类型

Spring AOP有5种通知类型,具体如表1-5所示。

表1-5 Spring AOP的5种通知类型

1.6.5 AOP的代码实现

在Spring中,AOP的使用比较简单,如下代码通过@Aspect注解声明一个切面,通过@Pointcut定义需要拦截的方法,然后用@Before、@AfterReturning、@Around分别实现前置通知、后置通知和环绕通知要执行的方法。