SpringBoot项目多个数据源冲突

项目启动出错:

The bean 'dataSource', defined in class path resource [com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceAutoConfigure.class], could not be registered. A bean with that name has already been defined in class path resource [com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceAutoConfiguration.class] and overriding is disabled.

这个错误表明在你的Spring Boot项目中,有两个配置类尝试定义名为dataSource的Bean,但是Spring Boot的默认行为是不允许同一个上下文中存在两个同名的Bean的,除非明确指定了允许覆盖(overriding)。

在这个具体的例子中,DruidDataSourceAutoConfigure类(来自Alibaba Druid数据库连接池)和DynamicDataSourceAutoConfiguration类(来自Baomidou Dynamic DataSource,可能用于多数据源配置)都试图定义名为dataSource的Bean。

要解决这个问题,你可以采取以下几种方法之一:

  1. 排除自动配置
    你可以在@SpringBootApplication注解所在的类上,使用@SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class, DynamicDataSourceAutoConfiguration.class})来排除这两个自动配置类。然后,你可以手动配置你所需的数据源。

  2. 手动配置数据源: 你也可以选择不使用自动配置,而是手动定义你的数据源配置。这样,你可以更精确地控制数据源的创建和管理。在你的配置类中使用@Bean注解来创建和配置DataSource。(最终用这种方式解决了问题)。使用@Configuration注解标记配置类,并使用@Bean注解创建数据源实例。这里以HikariCP为例,它是一个高性能的JDBC连接池:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.beans.factory.annotation.Value;
    import com.zaxxer.hikari.HikariDataSource;
    
    import javax.sql.DataSource;
    
    @Configuration
    public class DataSourceConfig {
    
        @Value("${spring.datasource.url}")
        private String dbUrl;
    
        @Value("${spring.datasource.username}")
        private String dbUsername;
    
        @Value("${spring.datasource.password}")
        private String dbPassword;
    
        @Value("${spring.datasource.driver-class-name}")
        private String dbDriverClassName;
    
        @Bean
        public DataSource dataSource() {
            HikariDataSource dataSource = new HikariDataSource();
            dataSource.setJdbcUrl(dbUrl);
            dataSource.setUsername(dbUsername);
            dataSource.setPassword(dbPassword);
            dataSource.setDriverClassName(dbDriverClassName);
            // 设置其他HikariCP特有的配置...
            return dataSource;
        }
    }

    application.propertiesapplication.yml文件中,设置数据库连接的相关属性:

    # application.properties spring.datasource.url=jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=your_password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  3. 指定Bean名称
    如果你确实需要两个数据源(例如,一个主数据源和一个从数据源),你可以确保这两个自动配置的数据源有不同的名称,然后在你的应用中通过名称来引用它们。这通常需要在你的application.propertiesapplication.yml中指定数据源的别名,或者在Java配置中自定义数据源Bean的名称。

  4. 使用@ConditionalOnMissingBean
    如果可能的话,你可以修改自动配置类,使用@ConditionalOnMissingBean注解来确保只有在没有同名的Bean时才创建该Bean。但是,由于这两个类都是第三方库提供的,你可能没有权限修改它们。

  5. 调整Spring Boot版本或依赖版本
    有时,这种冲突可能是由不同版本的库之间的不兼容引起的。确保你使用的所有Spring Boot相关依赖都是兼容的,并尝试升级或降级相关库的版本,以查看是否可以解决冲突。

  6. 查看文档和社区
    查看Alibaba Druid和Baomidou Dynamic DataSource的官方文档,看看是否有关于如何在同一个项目中使用它们的指南或建议。此外,也可以搜索相关的社区和论坛,看看其他人是如何解决类似问题的。

### 配置多个JPA数据源 为了在Spring Boot应用程序中设置和使用多个JPA数据源,需要遵循特定的配置模式来确保每个数据源都能被正确识别并独立工作。以下是实现这一目标的方法: #### 添加必要的依赖项 首先,在`pom.xml`文件中加入两个重要的启动器:一个是用于数据库连接池的数据源启动器(如HikariCP),另一个是`spring-boot-starter-data-jpa`,这使得能够轻松地集成JPA到项目当中[^2]。 ```xml <dependencies> <!-- 数据库驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!-- JPA支持 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- HikariCP作为默认的数据源实现 --> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> </dependency> </dependencies> ``` #### 创建主数据源配置类 创建一个新的Java类命名为`PrimaryDataSourceConfig.java`,在这个类里通过`@ConfigurationProperties(prefix="primary.datasource")`指定前缀来自定义第一个数据源的相关属性,并标记它为主数据源(`@Primary`)以便当存在多个相同类型的bean时优先考虑这个实例[^1]。 ```java @Configuration @EnableTransactionManagement public class PrimaryDataSourceConfig { @Bean(name = "primaryDataSource") @Primary @ConfigurationProperties(prefix = "primary.datasource") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "entityManagerFactory") @Primary public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) { HashMap<String, Object> properties = new HashMap<>(); properties.put("hibernate.hbm2ddl.auto", "update"); properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect"); return builder.dataSource(dataSource) .packages("com.example.primary.entity") .properties(properties) .persistenceUnit("primaryPersistenceUnit") .build(); } } ``` #### 创建次级数据源配置类 同样地,再建立一个名为`SecondaryDataSourceConfig.java`的新类用来管理第二个数据源及其对应的实体管理和事务处理逻辑。注意这里不再标注为`@Primary`,因为这不是首选的数据源。 ```java @Configuration @EnableTransactionManagement public class SecondaryDataSourceConfig { @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "secondary.datasource") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("secondaryDataSource") DataSource dataSource) { HashMap<String, Object> properties = new HashMap<>(); properties.put("hibernate.hbm2ddl.auto", "update"); properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect"); return builder.dataSource(dataSource) .packages("com.example.secondary.entity") .properties(properties) .persistenceUnit("secondaryPersistenceUnit") .build(); } } ``` #### 应用程序属性文件中的多数据源配置 最后一步是在项目的application.properties或application.yml文件内分别声明两组不同的数据源参数,每组都应具有唯一的名称空间以防止冲突。例如对于YAML格式的应用程序配置如下所示。 ```yaml primary: datasource: url: jdbc:mysql://localhost:3306/first_db?useSSL=false&serverTimezone=UTC username: root password: secret driver-class-name: com.mysql.cj.jdbc.Driver secondary: datasource: url: jdbc:mysql://localhost:3307/second_db?useSSL=false&serverTimezone=UTC username: root password: another_secret driver-class-name: com.mysql.cj.jdbc.Driver ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

因上精进,果上随缘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值