Joy
Joy

Reputation: 4483

Capturing annotated parameter with aspect in Spring boot application

with aspect, I am trying to capture annotated parameters, but it is not working.

Annotation is as follows:

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

The service class where I have annotated the parameters in a few methods are as follows:

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

Now with the help of aspect, I am trying to capture those annotated parameters as follows:

@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;
  }
}

I am clueless regarding how to capture the annotated parameter with aspect. Could anyone please help here? Thanks.

Upvotes: 1

Views: 1751

Answers (1)

kriegaex
kriegaex

Reputation: 67317

Firstly, if I were you I would pass on the annotation type as Class<?> from getAnnotatedParameter to isParamAnnotatedWith in order to make processing easier.

The actual bug in your code is that you use getClass() on an annotation instance, which always yields a JDK dynamic proxy class, because this is what it is internally in Java. Instead, you ought to use method annotationType(), which gives you exactly what you need.

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;
}

Upvotes: 3

Related Questions