在 Spring 引导应用程序中捕获带有 aspect 的注释参数

Capturing annotated parameter with aspect in Spring boot application

对于 aspect,我正在尝试捕获带注释的参数,但它不起作用。

注释如下:

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DTO {}

服务class我在几个方法中标注了参数如下:

@Service
class MyService {
  public MyDTO update(@DTO MyDTO myDTO) {
    // ...
  }
}

现在借助 aspect,我正尝试如下捕获那些带注释的参数:

@Aspect
class MyAspect {
  // ...

  @Before(value = "applicationServicePointcut()", argNames = "joinPoint")
  public Object process(ProceedingJoinPoint joinPoint, StateManagement stateManagement)
    throws Throwable {
      // ...
      // HERE I AM ALWAYS GETTING NULL
      Object object = getAnnotatedParameter(joinPoint, DTO.class);
      // ...
  } 

  public Object getAnnotatedParameter(JoinPoint joinPoint, Class<?> annotatedClazz) {
    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
    Parameter[] params = methodSignature.getMethod().getParameters();
    for (Parameter param : params) {
      if (isParamAnnotatedWith(param, annotatedClazz.getName())) 
      {
        return param;
      }
    }
    return null;
  }

  private boolean isParamAnnotatedWith(Parameter param, String annotationClassName) {
    for (Annotation annotation : param.getAnnotations()) {
      System.out.println("Annotation class name : " + annotation.getClass().getName());
      // HERE IN annotation.getClass().getName() I am getting com.sun.proxy.$Proxy375
      if (annotation.getClass().getName().equals(annotationClassName)) {
        return true;
      }
    }
    return false;
  }
}

我对如何用 aspect 捕获带注释的参数一无所知。有人可以在这里帮忙吗?谢谢

首先,如果我是你,我会将 Class<?> 的注释类型从 getAnnotatedParameter 传递到 isParamAnnotatedWith 以使处理更容易。

您代码中的实际错误是您在注释实例上使用了 getClass(),它总是产生一个 JDK 动态代理 class,因为这是它内部的内容Java。相反,您应该使用方法 annotationType(),它可以满足您的需求。

public Object getAnnotatedParameter(JoinPoint joinPoint, Class<?> annotationType) {
  Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
  for (Parameter parameter : method.getParameters()) {
    if (isParamAnnotatedWith(parameter, annotationType))
      return parameter;
  }
  return null;
}

private boolean isParamAnnotatedWith(Parameter parameter, Class<?> annotationType) {
  for (Annotation annotation : parameter.getAnnotations()) {
    if (annotation.annotationType().equals(annotationType))
      return true;
  }
  return false;
}