在SpringBoot中使用SpringAOP
概念
- 连接点(join point):类里面可以被增强的方法就是连接点。
- 切点(point cut):对接入点进行拦截的定义规则。
- 通知(advice):拦截到接入点后,进行的操作。分为以下五种操作:
- 前置通知(before advice):在连接点执行前执行
- 后置通知(after advice):在连接点执行后执行
- 环绕通知(around advice):在连接点执行前后执行,将连接点包含其中
- 返回通知(afterReturning advice):在连接点正常执行后执行,异常后不执行
- 异常通知(afterThrowing advice):在连接点异常时执行
- 目标对象(target):被代理的对象,也就是连接点所在的类。
- 引入(introduction):是指引入新的类和其他方法,增强现有Bean的功能。
- 织入(weaving):它是一个通过动态代理技术,为原有服务对象生成代理对象,然后将与切点定义匹配的连接点拦截,并按约定将各类通知织入约定流程的过程。
- 切面(aspect):是一个可以 定义切点、各类通知和引用 的内容。
使用
引入依赖
在pom文件中引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
新建切面
新建类 MyAspect 当作切面,在类上增加 @Aspect
注解声明切面:
@Aspect
@Component
@Slf4j
public class MyAspect {
}
定义切点
在切面MyAspect中,新建一个方法并使用 @Pointcut
注解声明切点:
@Aspect
@Component
@Slf4j
public class MyAspect {
/**
* 定义切点规则
*/
@Pointcut("execution(* com.ab.service.impl..*.*(..))")
public void pointCut() {}
}
execution(* com.ab.service.impl..*.*(..))
代表的含义如下:
execution
:代表所要执行的表达式主体
*
:代表方法返回类型 , *
代表所有类型
com.ab.service.impl
:包名代表aop监控的类所在的包
..
:代表该包以及其子包
*
:代表类名
*(..)
:*
代表方法名,..
代表参数
指示器
arg() 限制连接点匹配参数为指定类型的执行方法。
@args() 限制连接点匹配参数由指定注解标注的执行方法。
execution() 用于匹配的是连接点的执行方法。
this() 限制连接点匹配AOP代理的Bean引用为指定类型的类。
target() 限制连接点匹配目标对象为指定类型的类。
@target() 限制连接点匹配特定的执行对象,这些对象对应的类具备指定类型的注解。
within() 限制连接点匹配指定的类型。
@within() 限制连接点匹配指定注解所标注的类型(当使用Spring AOP时,方法定义再由指定的注解所标注的类里)。
@annotation 限制匹配带有指定注解连接点。
定义通知
在切面MyAspect中,新建一个方法并使用 @Before
注解声明前置通知:
@Aspect
@Component
@Slf4j
public class MyAspect {
/**
* 定义切点规则
*/
@Pointcut("execution(* com.ab.service.impl..*.*(..))")
public void pointCut() {}
/**
* 前置通知
* 也可使用此方式:@Before("execution(* com.ab.service.impl..*.*(..))")
*/
@Before("pointCut()")
public void before() {
log.info("前置通知");
}
}
环绕通知
环绕通知使用 @Around
注解:
/**
* 环绕通知
* 也可使用此方式:@Around("execution(* com.ab.service.impl..*.*(..))")
*/
@Around("pointCut()")
public Object Around(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("开始通知");
// 回调目标对象的原有方法
Object proceed = joinPoint.proceed();
log.info("结束通知");
// 返回目标对象的返回值
return proceed;
}
使用AOP的优点
- 集中处理某一关注点
- 侵入性少,增加代码可读性和可维护性
应用场景
- 权限控制
- 事务控制
- 缓存控制
- 审计日志
- 性能监控
- 分布式追踪
- 异常处理
参考:
https://blog.csdn.net/SunnyYoona/article/details/50655462
https://www.imooc.com/learn/869