Issue
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.
Answered By - Strelok