在下面的参考文章中,AOP已经介绍得比较详细了,但是由于本人不常用(从来没用过) AOP ,所以算是非常生疏,因此借此契机再次了解一遍 AOP,
【Spring】009-AOP
https://blog.csdn.net/qq_29689343/article/details/108410074
<!--aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
package com.zibo.api.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class HelloService {
public String getName(){
log.warn("HelloService ==> getName");
return "zibo";
}
public String getInfo(){
log.warn("HelloService ==> getInfo");
return "no info";
}
}
package com.zibo.api.aop;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Slf4j
public class LogAspect {
@Pointcut("execution(* com.zibo.api.service.*.*(..))")
public void pc1(){
}
@Before("pc1()")
public void before(JoinPoint jp){
String name = jp.getSignature().getName();
log.warn(name + "方法开始执行……");
}
@After("pc1()")
public void after(JoinPoint jp){
String name = jp.getSignature().getName();
log.warn(name + "方法执行结束……");
}
@AfterReturning(value = "pc1()", returning = "result")
public void afterReturning(JoinPoint jp, Object result){
String name = jp.getSignature().getName();
log.warn(name + "方法返回值为" + result);
}
@AfterThrowing(value = "pc1()", throwing = "e")
public void afterThrowing(JoinPoint jp, Exception e){
String name = jp.getSignature().getName();
log.warn(name + "方法抛出异常,异常为" + e.getMessage());
}
@Around("pc1()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
// 获取方法名
String methodName = pjp.getSignature().getName();
// 获取方法参数
Object[] args = pjp.getArgs();
// 记录方法开始时间
long startTime = System.currentTimeMillis();
log.info("方法 {} 开始执行,参数:{}", methodName, args);
Object result;
try {
// 执行目标方法
result = pjp.proceed();
} catch (Throwable throwable) {
// 记录异常信息
log.error("方法 {} 执行过程中抛出异常:{}", methodName, throwable.getMessage());
throw throwable; // 继续抛出异常
}
// 记录方法结束时间
long endTime = System.currentTimeMillis();
// 计算执行时间
long executionTime = endTime - startTime;
log.info("方法 {} 执行完毕,返回值:{},执行时间:{} ms", methodName, result, executionTime);
return result;
}
}
(省略)
@Aspect 注解:表明这是一个切面类;
@Pointcut 注解:表明这是一个切入点,execution 中第一个 * 表示任意返回值,第二个 * 表示包下的任意类,第三个 * 表示类中的任意方法,括号内两个 … 表示任意参数;
@Before 注解:表明这是一个前置通知,在目标方法执行前执行,通过 JoinPoint 参数可以获取目标方法的方法名、修饰符等信息;
@After 注解:表明这是一个后置通知,在目标方法执行后执行;
@AfterReturning 注解:表明这是一个返回通知,在该方法中可以获取目标方法的返回值,@AfterReturning 注解的 returning 参数是指返回值的变量名,对应方法的参数。注意,在方法参数中定义了 result 的类型为 Object 表明目标方法的返回值可以是任意类型,如果 result 的类型为 Long ,则该方法只能处理返回值为 Long 类型的情况。
@AfterThrowing 注解:表明这是一个异常通知,即当目标方法发生异常时该方法会被调用,异常类型为 Exception 表示所有的异常都会进入该方法中执行,若异常类型为 ArithmeticException ,则表示只有目标方法抛出的 ArithmeticException 异常才会进入该方法执行。
@Around 注解:表明这是一个环绕通知,环绕通知是所有通知中最强大的通知!可以实现前置通知、后置通知、异常通知以及返回通知的功能。目标方法进入环绕通知后,可以通过调用 ProceedingJoinPoint 对象的 proceed 方法使目标方法继续执行,开发者可以哦那个给修改目标方法的执行参数、返回值等,并且可以在此处理目标方法的异常。