AOP
是Aspect-oriented Programming
的缩写,是Spring的两大核心概念之一(另一概念是IoC)。
初次接触AOP编程,会被一些术语搞懵,本文就简单介绍一下这些术语的概念,与读者共勉。
Aspect(切面)
Aspect
的作用是对具有横切性质的业务逻辑进行集中处理,典型的应用就是Spring中的事务管理功能。
在Spring中,可以用注解@Aspect
定义一个类为一个切面,也可以采用XML的形式定义一个类为切面。在切面类中我们需要定义pointcut
(切入点),advice
(通知)。Spring会在符合pointcut
定义的join point
(连接点)处应用advice
。
Join point(连接点)
程序执行过程中的某个点,如方法执行或异常处理。对于Spring AOP来说,join point
仅代表方法执行。
Advice(通知)
在aspect
中进行定义,对满足pointcut
定义的join point
进行额外的功能增强(扩展)。Spring AOP是以拦截器的形式来对join point
应用advice
的。
Type of Advice(通知类型)
- Before advice:在
join point
之前执行的advice
。当且仅当在before advice
中抛出异常时,程序才可能不执行join point
。即原有的业务方法一定会被执行,无法用before advice
进行拦截处理,除非before advice
中抛出了异常。 - After returning advice:在
joint point
正常运行结束(不抛出异常)之后执行的advice
。 - After throwing advice:在
joint point
抛出异常之后执行的advice
。 - After (finally) advice:无论
joint point
是否抛出异常,都会执行的advice
。 - Around advice:最强大的一种通知,既可以在
joint point
之前进行增强,也可以在joint point
之后进行增强,甚至可以对joint point
进行拦截处理(即选择不执行原有的业务方法)。
尽管around advice很强大,甚至可以代替before advice和after returning advice,但实际选择通知类型的时候,还是需要和具体的业务逻辑相结合,选择最小最贴切的通知类型。如果想根据join point
的返回结果更新缓存值,最好使用after returning advice。虽然around advice也能满足需求,但在around advice中需要调用JointPoint
类中的proceed()
方法(即需要手动调用原有的业务逻辑方法),这显然会增加程序出错的可能性。
Pointcut(切入点)
Pointcut
之于join point
就像正则表达式之于字符串,pointcut
为join point
提供了一种模式定义。Spring AOP中使用了AspectJ的pointcut
模式定义语言,具体语法请见Spring AOP之pointcut语法
Introduction(引入)
Introduction
代表为一个类添加的新字段或方法定义。Spring AOP允许我们为任何对象introduce
(引入)新的接口实现,比如我们可以使用introduction
让一个bean实例实现IsModified
接口,以简化缓存处理逻辑。
Target object(目标对象)
Target object
是被一个或多个Aspect
增强的对象。Spring AOP是通过运行时生成代理类来实现的,target object
就是那个被代理的对象。
AOP proxy(AOP代理对象)
AOP proxy
就是target object
被增强后的对象,在Spring AOP中是通过JDK动态代理或者CGLIB代理技术实现的。
Weaving(织入)
Weaving
就是用aspect
增强target object
,使其成为AOP proxy
的过程,可以在编译时期(如ApsectJ编译器)、载入时期或运行时期进行。Spring AOP在运行时为target object
织入aspect
。
References
Spring Framework 5.2.5 Reference Doc.