3

Want to create annotation which will contain multiple annotations but want to make it more configurable so that it can be more feasible to use in all scenarios

@SpringBootApplication
@ServletComponentScan(basepackages="com.example.commons.traceability")
@ComponentScan(basePackages={
    "com.example.commons.security",
    "com.example.commons.restTemplate",
    "com.example.commons.logging",
})
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Microservice{
    String[] scanBasePackages() default {};
}

I want to use this application in Spring Application file but also want to make the componentScan more configurable so that apart from the default packages other package can also me included in the component scan

@Microservice(scanBasePackages={"com.example.myproject"})
public class MySpringApplciation{
    public static void main (final String[] args){
    // some code
    }
}

so as in the above code if I pass value of scanBasePackages so those packages should also be included in the component scan.

Is there any way to include values of scanBasePackages inside componentScan in custom annotation ?

aeroboy
  • 149
  • 4
  • 14

1 Answers1

1

Annotations on (custom) annotations are called meta-annotations.

In short: you're lucky. While Java does not allow this out of the box, Spring has a special annotation for this sort of thing: @AliasFor.

I had a similar question, and I found the answer here. And here is a good source.

Specifically in your case, try this:


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.annotation.AliasFor;

@SpringBootApplication
@ServletComponentScan(basePackages="com.example.commons.traceability")
@ComponentScan(basePackages={
  "com.example.commons.security",
  "com.example.commons.restTemplate",
  "com.example.commons.logging",
})
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Microservice{

  // >>> TRY THIS <<<
  @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
  String[] scanBasePackages() default {};
}

(I myself am less lucky, since I need this sort of thing for reducing my JUnit5 boilerplate annotations, and @AliasFor is only meaningful in Spring.)

bmel
  • 21
  • 3