Spring-boot: Spring Boot 2.1.0 Erroneous BeanDefinitionOverrideException

Created on 31 Oct 2018  路  2Comments  路  Source: spring-projects/spring-boot


Since the release of Spring Boot 2.1.0, I get the following error

org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'exampleBean' defined in MyTestConfiguration: Cannot register bean definition [... defined in [MyTestConfiguration.class]] for bean 'exampleBean': There is already [... defined in class path resource [ActualConfiguration.class]] bound.

In my ActualConfiguration class, the exampleBean is annotated with @ConditionalOnMissingBean(name="exampleBean"). When I ran my tests on Spring Boot 2.0.6, this worked, the exampleBean in the MyTestConfiguration class was used for specific tests, in all other instances the exampleBean in the ActualConfiguration class was used.

ActualConfiguration class

@Configuration
public class ActualConfiguration {

    @Bean
    @ConditionalOnMissingBean(name = "exampleBean")
    public ExampleBean exampleBean() {
        return new ExampleBean();
    }
}

TestConfiguration class

@TestConfiguration
public static class MyTestConfiguration {

    @Bean
    public ExampleBean exampleBean() {
        return new ExampleBean();
    }
}

I don't fully understand why Spring Boot 2.1.0 would throw the BeanDefinitionOverrideException if the actual exampleBean is annotated with @ConditionalOnMissingBean. Could you clarify for me whether this is intended behaviour?

invalid

Most helpful comment

This is expected behaviour. ActualConfiguration has been processed first and has defined the bean named exampleBean as no bean with that name had been defined at that point. MyTestConfiguration is then processed and it attempts to define exampleBean which fails as ActualConfiguration has already defined it.

This sort of ordering issue is why the javadoc for @ConditionalOnMissingBean strongly recommends that it is only used in auto-configuration:

The condition can only match the bean definitions that have been processed by the application context so far and, as such, it is strongly recommended to use this condition on auto-configuration classes only.

You may also want to consider enabling bean definition overriding in your test using spring.main.allow-bean-definition-overriding=true.

All 2 comments

This is expected behaviour. ActualConfiguration has been processed first and has defined the bean named exampleBean as no bean with that name had been defined at that point. MyTestConfiguration is then processed and it attempts to define exampleBean which fails as ActualConfiguration has already defined it.

This sort of ordering issue is why the javadoc for @ConditionalOnMissingBean strongly recommends that it is only used in auto-configuration:

The condition can only match the bean definitions that have been processed by the application context so far and, as such, it is strongly recommended to use this condition on auto-configuration classes only.

You may also want to consider enabling bean definition overriding in your test using spring.main.allow-bean-definition-overriding=true.

@wilkinsona Thanks for the help and the quick reply 馃憦

Was this page helpful?
0 / 5 - 0 ratings