Spring 教程

Spring 笔记

Spring AOP 中 JoinPoint 如何获取参数值、参数名称、方法名称、返回值、注解等

Spring 笔记 Spring 笔记


Spring AOP 是除了 IoC 之外的 Spring 另一个核心特性,通过“面向切面编程”可以在指定的 controller、service、dao 层等,无感知无侵入性地嵌入逻辑;切面编程的方法参数主要是 JoinPoint 接口对象,那么针对被切面的相关信息如参数值、参数名称、方法名称、返回值、注解等都需要通过 JoinPoint 对象来获取。

参数值

@Before("pointSign()")
public void doBefore(JoinPoint joinPoint) {
    Object[] args = joinPoint.getArgs();
    ...
}

通过如上方法,可以获取被切面方法的参数值,返回 Object[] 对象数组,数组的顺序与被切方法参数顺序一致。

java 基本类型的参数都会返回对应的封装类型,如 int 类型参数在这里返回 java.lang.Integer 类型。

参数名称

在 Java 8 之前,代码编译为 class 文件后,方法参数的类型固定,但是方法名称会丢失,方法名称会变成 arg0、arg1、…。从 Java 8 开始,在 class 文件中保留了参数名,所以在 java 8 开始也可以在 AOP 中获取参数名称。

MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String[] parameterNames = methodSignature.getParameterNames();

方法名称

String methodName = joinPoint.getSignature().getName()

返回值

Spring AOP 获取被切面方法的返回值有两种方式,一个是在 @Around 环绕通知里获取,另一个是 @AfterReturning 里获取,具体如下:

@Pointcut("execution(public int org.demo.service.AOPService.demoAOP(..))")
public void pointSign() {}

@Around("pointSign()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) {

    try {
        //  调用目标方法,返回目标方法返回值
        Object obj = proceedingJoinPoint.proceed();
        System.out.println("doAround return type:" + obj.getClass());
        System.out.println("doAround return value:" + obj);
        return obj;
    } catch (Throwable throwable) {

    } finally {

    }

    return null;
}

@AfterReturning(returning = "ret", value = "pointSign()")
public void doAfterReturning(JoinPoint joinPoint, Object ret) {
    //  ret 也是目标方法返回值
    System.out.println("doAfterReturning return type:" + ret.getClass());
    System.out.println("doAfterReturning return value:" + ret);
}

注解

MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);