AOP基础 快速入门
通过动态代理技术,完成对特定方法的编程
@Around设置AOP函数需要在哪个层的函数中进行运行
.表示任意的方法,. (…)表示任意的形参
定义一个Aop函数
@Component
@Aspect //表示当前类为Aop类
@Slf4j
public class aop {
@Around ("execution(* com.yuyu.realproject.Controller.*.*(..) )") //切入点表达式
public Object reportTime(ProceedingJoinPoint jointPoint) throws Throwable {
Long begin = System.currentTimeMillis();
Object result = jointPoint.proceed();
Long end = System.currentTimeMillis();
log.info(jointPoint.getSignature ( ).toLongString ()
+ "函数执行完成,共耗时{}",end-begin);
return result;
}
}
执行了Controller层的方法,总共耗时291ms
核心概念
通过动态代理对目标对象进行了功能增强
实际上最后注入的是动态代理之后的对象而非原始的目标对象。
AOP进阶
通知类型
环绕方法在原始方法出现异常之后,也不会继续执行
@PointCut表达式,进行表达式的抽取
如果定义为私有只能在当前类中使用
@PointCut(“...”)
void pt(){}
通知顺序
这些类中定义的通知,哪些先执行?
默认按照类名进行排序
切入点表达式
execution
通知方法只要有相对应的函数就会执行
*只匹配一个参数,…表示任意个数
表示匹配DeptService接口中所有带Integer类型参数的函数
表示以所有的以Service结尾的类,所有以delete开始的函数
表示匹配com包下,任意层级后的DeptService类。具体有多少层级无所谓
*(…)表达式匹配当前环境下所有包中的所有函数
或关系用 || 分割
建议:
annotation
annotation用来标识有特定注解的方法
自己定义注解
Retention用来定义注解什么时候生效,Target用于指定注解修饰的对象
上述标识表示本注解在运行时对函数方法使用
需要组合才能进行描述,可以用annotation表达式进行简化
小结:
连接点
methodName 方法名
className 类名
getArgs 获取方法传递的参数
.proceed 获得返回值
AOP通过获取返回值可以对函数的返回值进行篡改
案例
困飞了,不想写了
命名规则不一样而且没有规律,所以使用annotation自定义注解的方式进行切入
用户ID需要从Jwt令牌中获取,Jwt令牌储存在token中。所以注入request对象,然后直接获取token进行解析