javaspringspring-bootannotationsproperty-placeholder

Interface Annotation does not accept application.properties value


I have developed a simple Annotation Interface

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
    String foo() default "foo";
}

then I test it annotating a Class

@CustomAnnotation
public class AnnotatedClass {
}

and call it using a method

public void foo()  {
    CustomAnnotation customAnnotation = AnnotatedClass.class.getAnnotation(CustomAnnotation.class);
    logger.info(customAnnotation.foo());
}

and all works fine because it logs foo. I try also change the annotated class to @CustomAnnotation(foo = "123") and all works fine too, becuase it logs 123.

Now I want that the value passed to the annotation is retrieved by the application.properties, so I have changed my annotated class to

@CustomAnnotation(foo = "${my.value}")
public class AnnotatedClass {
}

but now the log returns the String ${my.vlaue} and not the value in application.properties.

I know that is possible use ${} instruction in annotation because I always use a @RestController like this @GetMapping(path = "${path.value:/}") and all works fine.


My solution on Github repository: https://github.com/federicogatti/annotatedexample


Solution

  • You can't do something like directly as an annotation attribute's value must be a constant expression.

    What you can do is, you can pass foo value as string like @CustomAnnotation(foo = "my.value") and create advice AOP to get annotation string value and lookup in application properties.

    create AOP with @Pointcut, @AfterReturn or provided others to match @annotation, method etc and write your logic to lookup property for corresponding string.

    1. Configure @EnableAspectJAutoProxy on main application or setting up by configuration class.

    2. Add aop dependency: spring-boot-starter-aop

    3. Create @Aspect with pointcut .

      @Aspect
      public class CustomAnnotationAOP {
      
      
      @Pointcut("@annotation(it.federicogatti.annotationexample.annotationexample.annotation.CustomAnnotation)")
       //define your method with logic to lookup application.properties
      

    Look more in official guide : Aspect Oriented Programming with Spring