Cesar
Cesar

Reputation: 173

@AutoConfiguration runs before user-defined beans

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

Answers (2)

Cesar
Cesar

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

abiieez
abiieez

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

Related Questions