9

my custom annotation is:

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

    long versionId() default 0;
}

I want to achieve something like this, in which I can pass the method param "versionTo" to my custom annotation.

@CacheClear(versionId = {versionTo})
public int importByVersionId(Long versionTo){
    ......
} 

What should I do?

Danni Chen
  • 343
  • 1
  • 3
  • 14
  • The retention runtime, only says that you can use reflection to evaluate whether the method has an annotation or not. You can not give it parameters – AnAmuser Sep 15 '17 at 09:25
  • AOP can help you, have a look at AspectJ and this blog post for example: https://blog.jayway.com/2015/09/08/defining-pointcuts-by-annotations/. – sp00m Sep 15 '17 at 09:26

2 Answers2

7

You cannot pass the value, but you can pass the path of that variable in Spring Expression and use AOP's JoinPoint and Reflection to get and use it. Refer below:

Your Annotation:

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

    String pathToVersionId() default 0;
}

Annotation Usage:

@CacheClear(pathToVersionId = "[0]")
public int importByVersionId(Long versionTo){
    ......
} 

Aspect Class:

@Component
@Aspect
public class YourAspect {

   @Before ("@annotation(cacheClear)")
   public void preAuthorize(JoinPoint joinPoint, CacheClear cacheClear) {
      Object[] args = joinPoint.getArgs();
      ExpressionParser elParser = new SpelExpressionParser();
      Expression expression = elParser.parseExpression(cacheClear.pathToVersionId());
      Long versionId = (Long) expression.getValue(args);

      // Do whatever you want to do with versionId      

    }
}

Hope this helps someone who wants to do something similar.

Sahil Chhabra
  • 10,621
  • 4
  • 63
  • 62
6

That's not possible.

Annotations require constant values and a method parameter is dynamic.

Luciano van der Veekens
  • 6,307
  • 4
  • 26
  • 30