Require explicit Qualifier for autowiring

Viewed 54

Is it possible to declare a bean such that it can be only injected with matching qualifier?

@Configuration
public class MyConfig {
  @Bean @Qualifier("authenticated") RestTemplate authenticatedRestTemplate() {
    /* configure basic authentication */
  }
}

// some hypothetical random component from 3rd party library or another project
// should not accidentally autowire my authenticated restTemplate that sends credentials with requests
@Component
public class BarComponent {
  @Autowired RestTemplate restTemplate; // <-- this should fail because it has no qualifier
}

For now using this workaround:

@Bean @Primary @Lazy RestTemplate restTemplate() {
  throw new Error("No default restTemplate implementation");
}

however this is not entirely correct as it will not work with conditionals but should be good enough.


Update 2: replaced Foo and specific with a more concrete RestTemplate and authenticated that better illustrates the problem I'm trying to avoid.


Update 3: Using a wrapper object of separate type as suggested below would be correct but kind of annoying on the consumer side due to a need to unwrap before use. Unless there's some way to tell Spring to unwrap it before injecting (converters?).

@Component /* or register with @Bean in config */
public class AuthenticatedRestTemplateHolder {
  private final RestTemplate restTemplate;
  public AuthenticatedRestTemplateHolder() { /* initialize */ }
  public RestTemplate getRestTemplate() { return restTemplate; }
}


@Component
@lombok.RequiredArgsConstructor 
public class SomeIntendedConsumer {
  @Autowired private final AuthenticatedRestTemplateHolder authenticatedRestTemplateHolder;

  void someMethod() {
    authenticatedRestTemplateHolder.getRestTemplate().post(/*...*/);
  }
}
0 Answers
Related