<返回更多

SpringBoot配置多数据源Consider marking one of the beans as @Primary

2022-07-06  简书  蜗牛学技术
加入收藏

配置流程

(一)配置文件配置

#多源数据库配置
#第一数据库
spring.datasource.primary.url=jdbc:MySQL://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.primary.username=root
spring.datasource.primary.password=123456
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver

#第二数据库
spring.datasource.secondary.url=jdbc:mysql://localhost:3306/spring1?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver

(二)新建一个DataSourceConfig配置类,代码如下:

/**
 * 多数据源配置
 */
@Configuration
public class DataSourceConfig {
    /**
     * 第一数据源
     * @return
     */
    @Bean(name = "primaryDataSource")
    @Qualifier("primaryDataSource")
    @ConfigurationProperties(prefix="spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 第二数据源
     * @return
     */
    @Primary  //默认选择这个数据源进行执行
    @Bean(name = "secondaryDataSource")
    @Qualifier("secondaryDataSource")
    @ConfigurationProperties(prefix="spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 本例使用的是jdbcTemplate来进行测试,所以添加jdbcTemplate的支持如下
     * @param dataSource
     * @return
     */
    @Bean(name = "primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate(
            @Qualifier("primaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean(name = "secondaryJdbcTemplate")
    public JdbcTemplate secondaryJdbcTemplate(
            @Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

(三)新建测试用例

    @Autowired
    @Qualifier("primaryJdbcTemplate")
    protected JdbcTemplate jdbcTemplate1;

    @Autowired
    @Qualifier("secondaryJdbcTemplate")
    protected JdbcTemplate JdbcTemplate2;

    @Test
    public void test() throws Exception {
        //往第一数据库添加数据
        jdbcTemplate1.update("insert into user_test(name,age) values(?, ?)","多源数据库",150);
        //往第二数据库添加数据
        JdbcTemplate2.update("insert into user_test_1(name,age) values(?, ?)","多源数据库",150);
    }

(四)报错

JAVA.lang.IllegalStateException: Failed to load ApplicationContext

    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'learnController': Unsatisfied dependency expressed through field 'learnService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'learnServiceImpl': Unsatisfied dependency expressed through field 'learnDao'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'learnDaoImpl': Unsatisfied dependency expressed through field 'jdbcTemplate'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.jdbc.core.JdbcTemplate' available: expected single matching bean but found 2: primaryJdbcTemplate,secondaryJdbcTemplate

报错信息有几个,之前没有添加多源数据的时候正常,主要是后面这个报错:

SpringBoot配置多数据源Consider marking one of the beans as @Primary

主要问题报错位置

(五)报错分析

从字面意思可以知道,本来只需要一个bean,但是找到了两个bean,系统不知道需要用到哪一个bean,所以报错,而系统所找到的就是我们之前配置的两个多源数据写的bean。

回到刚才的配置类,我们发现,我们已经在第二数据源上面加上了@Primary,按道理来说,系统应该默认执行该方法,不至于说找不到需要选择执行哪个bean
等等.....
刚才我们添加的@Primary的方法只是用来读取配置文件该选择哪个数据库而已,但是对JdbcTemplate支持的方法并没有告诉系统该执行哪一个!!!!!
那么问题就很好解决了
真相只有一个......
在secondaryJdbcTemplate方法上添加@Primary注解,如下:

 @Primary
    @Bean(name = "secondaryJdbcTemplate")
    public JdbcTemplate secondaryJdbcTemplate(
            @Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

ok ,重新运行测试单元

SpringBoot配置多数据源Consider marking one of the beans as @Primary

久违的绿色又出来了

绿了绿了,哈哈哈,看一下数据库是否添加成功

SpringBoot配置多数据源Consider marking one of the beans as @Primary

看一下两个库的数据是否添加成功


SpringBoot配置多数据源Consider marking one of the beans as @Primary

数据添加成功,两个库中都有数据


原文来源链接:
https://www.jianshu.com/p/c2ec8a283a80

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>