springboot中的AOP以及面向切面编程思想
快速入门体验AOP
aop中相关概念
实现导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
新建aop文件夹,里面声明XXXAspect类
@Aspect // 声明一个aop类
@Component
public class RecordTimeAspect {
private static final Logger log = (Logger) LoggerFactory.getLogger(RecordTimeAspect.class);
// 切入点表达式
@Around("execution(* com.managerweb.service.ServiceImpl.*.*(..))") // 测试业务层的所有方法
public Object RecordTime(ProceedingJoinPoint pjp) throws Throwable {
long begin = System.currentTimeMillis();
Object result = pjp.proceed(); // 这表示执行所有@Around里声明的方法
long end = System.currentTimeMillis();
// getSignature()获取方法名称
log.info("方法{}运行时间为{}",pjp.getSignature(), (end - begin));
return result;
}
}
AOP的底层原理:动态代理
通知
根据通知方法执行时机的不同,将通知类型分为以下常见的五类:
- @Around: 环绕通知,此注解标注的通知方法在目标方法前、后都被执行
- @Before: 前置通知,此注解标注的通知方法在目标方法前被执行
- @After: 后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
- @AfterReturning: 返回后通知,此注解标注的通知方法在目标方法返回后执行,有异常不会执行
- @AfterThrowing: 异常后通知,此注解标注的通知方法发生异常时执行
- 注意1:@Around环绕通知需要自己调用 ProceedingJoinPoint.proceed() 来让原始方法执行,其它通知不需要考虑目标方法执行
- 注意2:@Around环绕通知方法的返回值,必须指定为Object,以接收目标方法的返回值。
抽取切入点表达式
抽取的原因:由于切入点表达式总是出现,为了简化,在最开始时将切入点表达式抽取出来
具体使用如下
@Pointcut("execution(* com.managerweb.service.ServiceImpl.*.*(..))")
private void pt(){}
@Around("pt()") // 测试业务层的所有方法
public Object RecordTime(ProceedingJoinPoint pjp) throws Throwable {
long begin = System.currentTimeMillis();
Object resu