Search code examples
javaspringspring-bootspring-bean

Spring default bean candidate


I'm writing a library that uses spring, for others to use. In my library, I have class A that has an interface B as a field (with @Autowired). I have a default implementation of that field, but the user can implement a custom implementation by himself. What I want to happen is the following: If the user implemented B, I want that bean to be injected to A, otherwise I want my default implementation to be injected. Something like the opposite of @Primary

I know that the user can add the @Primary annotation in order for that to happen, but I don't want him to add any other annotation besides @Component (because it is not clear for the user why he must add the @Primary annotation)

Is there a way to achieve this behavior? I've also tried @Order and @Priority, but no luck - the user must add another annotation.

Thanks!


Solution

  • You should create your own auto configuration. Auto configuration classes are always processed last so user's own configuration is processed first and when using @Conditional... annotations user's beans will take precedence.

    Your auto configuration class should look like this:

    @Configuration
    public class MyAutoConfiguration {
    
      @ConditionalOnMissingBean(B.class)
      @Bean
      public B defaultImplementation() { return A(); }
    
      @Bean
      public UsesB classThatUsesB(B b) { return UsesB(b); }
    
    }
    

    In this case if the user of your library defines a bean of type B it will always be used first and if they don't the bean created by the defaultImplementation method will be used.