Reputation: 173
I have an autoconfigure module in some starter, with this configuration:
@Configuration
public class AutoConfiguration {
@Bean
@ConditionalOnMissingBean
public SomeBeanInterface someBean() {
return new DefaultBean();
}
}
An the client module who uses it, has this one, which contains a custom bean:
@Configuration
public class UserConfiguration {
@Bean
public SomeBeanInterface someBean() {
return new CustomBean();
}
}
Everything works fine and custom bean is used by Spring instead of default. However, if i use @AutoConfiguration instead of regular @Configuration in the starter module (as recommended by current spring boot docs), then Spring picks the default bean.
As far as I could see, this happens because the "proxyBeanMethods = false" inside @AutoConfiguration. But i´m a little bit confused, as the documentation says: "auto-configuration classes are guaranteed to load after any user-defined bean definitions have been added" So, from my understanding, Spring should pick the Custom bean, as it should be loaded before the autoconfiguration class.
I'll appreciate any opinion, explanation of this behavior. Thank you!
Upvotes: 3
Views: 2636
Reputation: 173
I've just figured it out: there was another bean in the starter configuration calling the first one by method signature:
@AutoConfiguration
public class AutoConfiguration {
@Bean
@ConditionalOnMissingBean
public SomeBeanInterface someBean() {
return new DefaultBean();
}
@Bean
public SomeSecondBean secondBean() {
return new SomeSecondBean(someBean())
}
}
I've just changed it to:
@Bean
public SomeSecondBean secondBean(SomeBeanInterface
someBean) {
return new SomeSecondBean(someBean)
}
And everything worked fine
Upvotes: 0
Reputation: 3189
When you use @AutoConfiguration
, Spring Boot generates a proxy for the AutoConfiguration class with proxyBeanMethods = false
. This means that any @Bean methods in the AutoConfiguration class will not be intercepted by the proxy and will be called directly. Therefore, when you define a bean with the same name in the client module's UserConfiguration class, it is ignored because Spring Boot will use the bean definition from the AutoConfiguration class instead.
To make sure that the bean from the UserConfiguration class takes precedence, you can add the @ConditionalOnMissingBean
annotation to both the AutoConfiguration and UserConfiguration classes' @Bean
methods.
Upvotes: 1