0
@RestController
public class TestController {

    @GetMapping("/hello/{userId}")
    @Audit(type = AuditType.CREATE)
    public String hello(@AuditField @PathVariable long userId) {
        return "hello";
    }

}

I want to scan the @Audit Annotation along with @AuditField. THe @Audit scan works fine, but I want to get the @AuditField parameter value too. Here in my case userId.

I have defined the Aspect for @AfterReturning advice.

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;


@Aspect
@Component
public class AuditAspect {

  @AfterReturning(pointcut = "@annotation(audit)", returning = "result")
  public void audit(JoinPoint jp, Object result, Audit audit) throws Exception {

   List<Object> auditFields = getAuditData(jp.getArgs());
   System.out.println(auditFields);
  }

  private List<Object> getAuditData(Object[] args) {
    return Arrays.stream(args)
        .filter(arg -> arg instanceof AuditField)
        .collect(Collectors.toList());
  }
}

But while accessing hello/1, auditFields shows empty.

Gaurav Srivastav
  • 2,381
  • 1
  • 15
  • 18

1 Answers1

0

Your assumption that by annotating a method parameter it somehow becomes an instanceof the annotation class is wrong and quite illogical. What you need to do instead is to scan the method signature for parameter annotations and then return the method arguments at the corresponding positions of the method signature, similar to my sample code in those answers, each showing slightly different variations of your problem:

kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • But what about if there are multiple annotations used for a field. Then it will break. – Gaurav Srivastav Sep 01 '18 at 08:57
  • It is kind of hack I need better solution. – Gaurav Srivastav Sep 01 '18 at 08:57
  • A better solution does not exist because method parameter annotations cannot be bound to pointcut arguments. I cannot change AspectJ according to your wishful thinking, sorry. Either use reflection or forget it. You can wrap what you call a "hack" into a utility method and thus hide the complexity from the aspects using it. – kriegaex Sep 01 '18 at 09:47
  • And it will not break if a field has multiple annotations if done right. I updated my answer with links to several related answers I wrote here before. Choose what is closest to what you need and modify, if necessary. It is not so difficult, really. – kriegaex Sep 01 '18 at 10:21
  • I will check it. – Gaurav Srivastav Sep 01 '18 at 12:12