一、AOP 相关概念
AOP
含义:Aspect Oriented Programming ⾯向切⾯编程/⾯向⽅⾯编程。AOP
的应用场景:日志、鉴权、安全等。AOP
实现方式:JDK
动态代理或CGLib
动态代理。JoinPoint
(连接点)含义:简单理解就是某方法在被执行前、被执行后(方法顺利执行后)、执行异常时、执行结束时(无论异常与否都执行)。这几个特殊的时机点。即:你的功能增强代码可以放置的位置点。连接点是一种候选点,即:我们可以选择也可以不选择这个连接点。是所有可添加功能增强代码位置的总称。PointCut
(切入点)含义:将要被进行功能增强的方法。Advice
(增强/通知)含义:1)横切逻辑。(功能增强代码的执行逻辑)。 2)方位点。(方位点是指,具体的一个或多个被添加增强代码的连接点)- 范围排序:连接点 > 切入点 > 方位点
Target
(目标对象)含义:将要被代理(或增强)的对象。Proxy
(代理)含义:被动态代理技术添加完增强代码后的对象。Weaving
(织入)含义:是一个过程,即:把增强代码添加进被代理对象的这个过程。Aspect
(切面)含义: 切面 = 切入点 + 方位点 + 横切逻辑 (切入点明确要添加增强的方法,方位点明确增强方法添加的位置,横切逻辑就是具体的增强代码)
二、AspectJ 语法表达式
相信有不少同学和我一样,框架都是之前别人搭建好的,自己只是拿来按照之前的规则用。因此关于 AspectJ
的真正用法也是应了那句:懵逼树上懵逼果,懵逼树下你和我。所以下面将详细记录我是如何将一个只针对某个类的某个方法的增强,转换成针对多个类下的多个方法的增强的过程。
说明: AspectJ
语法表达式中,*
表示任意内容。
- 只针对
AccountServiceImpl
类下的参数为Account
的updateAccountByCardNo
方法增强。
<aop:pointcut id="pt1" expression="execution(public int com.idol.service.impl.AccountServiceImpl.updateAccountByCardNo(com.idol.pojo.Account))"/>
解读:访问修饰符(可省略) +
返回值类型的全限定类名(可用 *
代替任意返回值类型。如果返回值为基本数据类型则不用写全限定类型。) +
全限定类名(可用 *
代替某一层级的包,也可用 *..*
代替任意多层级的的) +
方法名(可用 *
代替任意方法名,也可用 *
补全方法名表示以指定内容开头的方法名) +
参数类型的全限定类型(可用 *
表示任意参数,但参数数量最少为一个;也可用 ..
表示任意个数的任意类型参数)
- 例如:我想对
com.idol.service.impl
包下的所有对象中,以update
开头的方法,进行增强。且不考虑返回值和参数类型。就可以写为:
<aop:pointcut id="pt1" expression="execution(* com.idol.service.impl.*.update*(..))"/>
三、AOP 用法注意
- 环绕型通知通常不与其他类型通知同时使用。
- 如果想要在
after-returning
增强中获取原函数的增强结果,必须在xml
中通过returning
属性指定结果参数名称。 - 如果想要在
after-throwing
增强中获取原函数的异常结果,必须在xml
中通过throwing
属性指定异常参数名称。
四、源码
源码中包含了纯注解模式和纯 xml
模式下的 AOP
的使用方式。
------------------- 人前有多光鲜,人后就有多黯淡 -------------------