title: Spring custom @Enable annotation meta-annotated with @ComponentScan
body: <p>I'm trying to write my own <code>@Enable</code> annotation for Spring framework, which should be used as follows:</p>
  
  <pre class="lang-java prettyprint-override"><code>package com.example.package.app;
  
  @SpringBootApplication
  @com.example.annotations.EnableCustom("com.example.package.custom")
  public class MyApplication {}
  </code></pre>
  
  <p>I followed <a href="https://stackoverflow.com/questions/47565859/component-scan-using-custom-annotation">Component scan using custom annotation</a>, but this poses several limitations:</p>
  
  <ol>
  <li><p>I cannot make the base package property dynamic, i.e. I cannot pass <code>"com.example.package.base"</code>, but need to pre-define the package at the configuration.</p>
  
  <p>I had a look at <code>@AliasFor</code>, but cannot get it to work.</p></li>
  <li><p>When I leave out the base package, scanning starts from the defining package of the annotation, not from the package of the annotated class. In above's example, it would only scan and create beans for classes in <code>com.example.annotations</code>, but not for <code>com.example.package.*</code>.</p>
  
  <p>I had a look at <code>EntityScanPackages.Registrar.class</code> which is imported in <code>@EntityScan</code> annotation, but it is an internal class and my annotation cannot import.</p></li>
  </ol>
  
  <p>Everything works if I put <code>@ComponentScan(includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = MyAnnotation.class))</code> on <code>MyApplication</code> class, but stops working when this is moved to a meta-annotation of <code>@EnableCustom</code>. How to tell Spring Framework to consider <code>@EnableCustom</code> as a different way of specifying <code>@ComponentScan</code> with some default values. I tried meta-annotating my annotation with <code>@Configuration</code>, <code>@Component</code> and others, to no avail:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Configuration
  @Target(ElementType.TYPE)
  @Retention(RetentionPolicy.RUNTIME)
  @ComponentScan(
          includeFilters = @ComponentScan.Filter(
                  type = FilterType.ANNOTATION,
                  value = ApplicationService.class))
  public @interface EnableApplicationServices {
      @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
      String[] value() default {};
  }
  </code></pre>
  
  <p>Where can I find documentation for this or what starting point would you recommend? My long term goal is to have a Spring Boot starter which can be used by a multitude of projects.</p>
  
  <hr>
  
  <p>A M(N)WE can be found in the following repository: <a href="https://github.com/knittl/stackoverflow/tree/spring-enable-annotation" rel="nofollow noreferrer">https://github.com/knittl/stackoverflow/tree/spring-enable-annotation</a></p>
  
  <p>Here's a rundown of the package structures:</p>
  
  <pre><code>// com.example.annotations.EnableCustom.java
  @Configuration
  @Target(ElementType.TYPE)
  @Retention(RetentionPolicy.RUNTIME)
  // this annotation is never honored:
  @ComponentScan(
          includeFilters = @ComponentScan.Filter(
                  type = FilterType.ANNOTATION,
                  value = MyAnnotation.class))
  //@Import(EnableCustom.EnableCustomConfiguration.class)
  public @interface EnableCustom {
      // this annotation works in combination with @Import, but scans the wrong packages.
      @ComponentScan(
              includeFilters = @ComponentScan.Filter(
                      type = FilterType.ANNOTATION,
                      value = MyAnnotation.class))
      class EnableCustomConfiguration {}
  }
  
  // file:com.example.app.Application.java
  @SpringBootApplication
  @EnableCustom("com.example.app.custom.services")
  // @ComponentScan(
  //         includeFilters = @ComponentScan.Filter(
  //                 type = FilterType.ANNOTATION,
  //                 value = MyAnnotation.class)) // &lt;- this would work, but I want to move it to a custom annotation
  public class Application {
  }
  
  // file:com.example.app.custom.services.MyService
  @MyAnnotation
  public class MyService {
      public MyService() {
          System.out.println("Look, I'm a bean now!");
      }
  }
  
  // file:com.example.annotations.services.WrongService.java
  @MyAnnotation
  public class WrongService {
      public WrongService() {
          System.out.println("I'm in the wrong package, I must not be instantiated");
      }
  }
  </code></pre>