title: Define a Spring RestController via Java configuration
body: <p>Is it possible to Define a Spring RestController (<code>@RestController</code> annotated class) <em>solely</em> in the Java Configuration (the class with <code>@Configuration</code> annotated in the method marked with <code>@Bean</code>)?</p>
  
  <p>I have an application managed by spring boot (the version doesn't matter for the sake of the question, even the last one available). This application exposes some endpoints with REST, so there are several rest controllers, which in turn call the services (as usual). </p>
  
  <p>Now depending on configuration (property in <code>application.yml</code>) I would like to avoid starting some services and, say 2 classes annotated with <code>@RestController</code> annotation because they deal with the "feature X" that I want to exclude.</p>
  
  <p>I would like to configure all my beans via <em>Java configuration</em>, and this is a requirement. So my initial approach was to define all the beans (controllers and services) in a separate configuration which is found by spring boot during the scanning) and put a <code>@ConditionalOnProperty</code> on the configuration so that it will appear in one place:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Configuration
  public class MyAppGeneralConfiguration {
    // here I define all the beans that are not relevant for "feature X"
    @Bean
    public ServiceA serviceA() {}
    ...
  }
  
  @Configuration 
  @ConditionalOnProperty(name = "myapp.featureX.enabled", havingValue = "true")
  public class MyAppFeatureXConfiguration {
     // here I will define all the beans relevant for feature X:
  
    @Bean
    public ServiceForFeatureX1 serviceForFeatureX1() {}   
  
    @Bean
    public ServiceForFeatureX2 serviceForFeatureX2() {}   
  }
  </code></pre>
  
  <p>With this approach My services do not have any spring annotations at all and I don't use <code>@Autowired</code> annotation as everything is injected via the constructors in <code>@Configuration</code> class:</p>
  
  <pre><code>// no @Service / @Component annotation
  public class ServiceForFeatureX1 {}
  </code></pre>
  
  <p>Now my question is about the classes annotated with <code>@RestContoller</code> annotation. Say I have 2 Controllers like this:</p>
  
  <pre><code>@RestController
  public class FeatureXRestController1 {
    ...
  }
  
  @RestController
  public class FeatureXRestController2 {
   ...
  }
  </code></pre>
  
  <p>Ideally I would like to define them in the Java Configuration as well, so that these two controllers won't even load when I disable the feature:</p>
  
  <pre><code>@ConditionalOnProperty(name = "myapp.featureX.enabled", havingValue = "true", matchIfMissing=true)
  public class MyAppFeatureXConfiguration {
  
      @Bean
      @RestController // this doesn't work because the @RestController has target Type and can't be applied 
                      // to methods
      public FeatureXRestController1 featureXRestController1() {
      } 
  </code></pre>
  
  <p>So the question is basically is it possible to do that?</p>
  
  <p>RestController is a Controller which is in turn a component hence its subject to component scanning. Hence if the feature X is disabled the rest controllers for feature X will still start loading  and fail 
  because there won't be no "services" - beans excluded in the configuration, so spring boot won't be able to inject.</p>
  
  <p>One way I thought about is to define a special annotation like <code>@FeatureXRestController</code> and make it <code>@RestController</code> and put <code>@ConditionalOnProperty</code> there but its still two places and its the best solution I could come up with:</p>
  
  <pre><code>@Target(ElementType.TYPE)
  @Retention(RetentionPolicy.RUNTIME)
  @Documented
  @RestController
  @ConditionalOnProperty(name = "myapp.featureX.enabled", havingValue = "true", matchIfMissing=true)
  public @interface FeatureXRestController {
  }
  
  ...
  @FeatureXRestController
  public class FeatureXRestController1 {...}
  
  @FeatureXRestController
  public class FeatureXRestController2 {...}
  </code></pre>