在Spring Boot 2.1中重写DataSource bean

时间:2018-11-01 15:47:40

标签: java spring spring-boot

我已升级到Spring Boot 2.1版本,并且在启动应用程序时遇到了奇怪的异常。

The bean 'dataSource', defined in BeanDefinition defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class] and overriding is disabled.

完整的错误消息是:

[o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext] Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'dataSource' defined in BeanDefinition defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Cannot register bean definition [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]] for bean 'dataSource': There is already [Root bean: class [null]; scope=refresh; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]] bound.

根据我们的政策,不得覆盖Bean,并通过以下方式禁用它:

spring.main.allow-bean-definition-overriding=false

我的应用程序代码中没有任何数据源配置。触发此错误的唯一选项是@EnableAutoConfiguration,在我的应用程序属性中,我已将数据源类型设置为:

spring.datasource.type=com.zaxxer.hikari.HikariDataSource

启动应用程序初始化为

@SpringBootApplication
@EnableAutoConfiguration
public class MyApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        new MyApplication()
            .configure(new SpringApplicationBuilder(MyApplication.class))
            .run(args);
    }
}

还有一个配置类可以导入其他各种配置:

@Configuration
@ImportResource(locations = {
    "classpath*:conf/spring/*.xml",
    "classpath*:conf/spring/core/*.xml",
    "classpath*:conf/spring/plugin/**/*.xml"
})
@EnableAsync
@EnableRetry
@EnableCaching
@EnableBatchProcessing
@EnableCircuitBreaker
public class AppConfig {
    ...
}

有人知道什么可能导致该问题以及在何处搜索吗?

在Spring Boot 2.1(即2.0.5)之前没有发生。

7 个答案:

答案 0 :(得分:22)

今天,我遇到了类似的问题,随后的春季云配置问题对我有所帮助:Issue 1142

到目前为止,我们正在使用与Spring Boot 2.1.0不兼容的Spring Cloud Config。 Spring Cloud的格林威治发布系列将与Spring Boot 2.1.0兼容。

您的@EnableCircuitBreaker注释使我相信您可能还使用的Spring Cloud版本与Spring Boot的2.1.0版本不兼容。

答案 1 :(得分:2)

在application.properties中添加以下属性可以解决该问题。

spring.main.allow-bean-definition-overriding = true

还可能需要添加另一个属性来解决提到的另一个问题: https://github.com/openzipkin/zipkin/issues/2043

management.metrics.web.server.auto-time-requests = false

答案 2 :(得分:0)

对于Spring Boot 2+,您可以排除自动配置

@SpringBootApplication(exclude = ElasticsearchDataAutoConfiguration.class)
     public class YourApplication {
 ... }

答案 3 :(得分:0)

我遇到了类似的问题,它非常通用(有时存在重复的注释,有时也存在重复的bean)查找问题所在的最佳方法是:

打开类DefaultListableBeanFactory 应该有这样的代码:

BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }

根据新抛出的内容放置一个断点。然后,现存的Definition.source.className指向已注册的配置,这就是问题所在。当您检查beanDefinition.source.className时,您将比较两个类并查找重复的代码或注释在哪里,只需删除/修复它们即可。

答案 4 :(得分:0)

当我尝试在项目中配置Redis时遇到了这个问题,最后我使用以下方法解决了该问题:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})

我使用SpringBoot 2.4.2

答案 5 :(得分:0)

我遇到了同样的问题,我在寻找更好,更通用的解决方案,结果发现:

1-在此处检查以查看哪些版本的Spring Cloud与您的启动版本兼容 spring cloud

2-之后,请转到此处选择您喜欢的确切版本spring cloud releases

这些步骤为我解决了问题,而无需进行其他任何配置。但是,对您来说,这可能是另一个不兼容的依赖关系。不一定是春天的云。

答案 6 :(得分:-1)

org.springframework.cloud:spring-cloud-context:2.0.2.RELEASE

RefreshAutoConfiguration在刷新其中的HikariDatasource时导致此问题

可能的解决方法是

spring.cloud.refresh.enabled = false