31

Consider I have defined the following aspect:

@Aspect
public class SampleAspect {

    @Around(value="@annotation(sample.SampleAnnotation)")
    public Object display(ProceedingJoinPoint joinPoint) throws Throwable {
        // ...
    }
}

and the annotation

public @interface SampleAnnotation {
    String value() default "defaultValue";
}

Is there a way to read the value parameter of the annotation SampleAnnotation in the display method if my aspect?

Thanks for your help, erik

Erik
  • 11,944
  • 18
  • 87
  • 126
  • 2
    possible duplicate of [Accessing Annotation-value in advice](http://stackoverflow.com/questions/5026247/accessing-annotation-value-in-advice) – axtavt Mar 12 '11 at 11:45

3 Answers3

49

Change the advice signature to

@Around(value="@annotation(sampleAnnotation)")
public Object display(ProceedingJoinPoint joinPoint, SampleAnnotation sampleAnnotation ) throws Throwable {
    // ...
}

and you will have access to the value in the annotation.

See docs for more info.

NealeU
  • 1,264
  • 11
  • 23
David Rabinowitz
  • 29,904
  • 14
  • 93
  • 125
  • 2
    for in depth documentation check out: http://docs.spring.io/spring/docs/3.0.3.RELEASE/spring-framework-reference/html/aop.html - section 7.2.4.6 Advice parameters – hoodieman Apr 21 '15 at 11:15
  • 7
    The subtle nuance here is that `@Around` value must contain an **argument name** instead of annotation's name. In this answer they are almost identical (the difference is just the case of first letter) so I was confused at first why it doesn't work in my code until I noticed the letter's case. – Ruslan Stelmachenko Dec 09 '21 at 11:56
8

Bellow I'll add a complete example of AOP implementation where I'll getting parameter from my Custom pointCut annotation, where my advice aim to calculate the time execution of a function:

1- Custom Annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationLogExecutionTime {

    public boolean isActivate() default false;

}

2- Controller:

@AnnotationLogExecutionTime(isActivate = true)
@PostMapping("/connection")
public HttpEntity<String> createAuthenticationToken(HttpServletRequest request,
                                                        @RequestBody AuthenticationRequest authenticationRequest) {...}

3- Advice

@Component
@Aspect
public class LoggingExecutionTimeAdvice {

    @Around("@annotation(annotationLogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint, AnnotationLogExecutionTime annotationLogExecutionTime) throws Throwable {

        if(annotationLogExecutionTime.isActivate()){//Here I recover the value!!!!
            long start = System.currentTimeMillis();
            Object proceed = joinPoint.proceed();
            long executionTime = System.currentTimeMillis() - start;
            System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
            return proceed;
        }
        Object proceed = joinPoint.proceed();
        return proceed;
    }
}

Explanation:

Our advice (logExecutionTime) will be excuted around (joinPoint) the function that will be annotated with AnnotationLogExecutionTime (our custom annotation) so I want to active or not this the calculation of time execution so I'll get the value from the membre of our custom annotation (which you ask about ;) )

BERGUIGA Mohamed Amine
  • 6,094
  • 3
  • 40
  • 38
0

I was confused on how to map this before.

@Before("@annotation(any_variable_name) && args(spring_will_find_its_type_to_match)")
public void myAdvice(JoinPoint joinPoint, MyAnnotation any_variable_name, MyClass spring_will_find_its_type_to_match) {
    System.out.println("before testing in Aspect myAdvice " + spring_will_find_its_type_to_match);
}
Abe
  • 310
  • 3
  • 15