Spring Cloud环境下多数据源的配置要点(实战)

 

最近在搭建Spring Cloud新项目,遇到了这个问题,记录一下,以飨读者。

 

关于怎么配置多数据源,这里不再赘述,简单来说,就是配置多个bean,每个bean对应一个数据源。

有不懂的读者,可以参考我之前的一篇博客,或者在网上搜素,都可以。

如何配置多数据源

这篇博客比较老了,用的是xml配置文件。但是万变不离其宗,本质上是一样的,就是注入多个bean到Spring的IOC容器中。

 

在Spring Cloud环境下,我们配置了2个数据源以后,启动项目会报错。

 

报错日志如下:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed;

nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource;

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [cn/sephora/platform/oms/backend/config/DataSourceConfig.class]: Initialization of bean failed;

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed;

nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: monitorDataSource,dataSource

 

更详细的堆栈日志如下:

2020-05-25 13:14:09,669 [main] ERROR org.springframework.boot.SpringApplication - [ -  - ] - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [cn/sephora/platform/oms/backend/config/DataSourceConfig.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: monitorDataSource,dataSource
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1054)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:829)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760)
	at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:306)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174)
	at cn.sephora.platform.oms.backend.Application.main(Application.java:26)

 

为什么呢?很简单,你配置了2个数据源,都是javax.sql.DataSource的实现。

DataSourceAutoConfiguration这个类也向IOC容器注入了一个DataSource,这个DataSource是Spring集成的原生的DataSource。

 

那么问题来了,当DataSourceAutoConfiguration向Spring的IOC容器中注入DataSource实例时,发现这个DataSource有2个实现,

Spring的IOC容器不知道该使用哪个?于是就抛出了上面的异常。

 

解决方案如下:在Spring启动时,不要加载这个DataSourceAutoConfiguration就行了。

如下:在SpringBootApplication注解上,排除掉DataSourceAutoConfiguration.class

 

@SpringBootApplication(exclude={
        DataSourceAutoConfiguration.class
})
public class Application {

    public static void main(String[] args) {

        SpringApplication.run(Application.class, args);
    }
}

 

这里告诉我们一个要点:Spirng Cloud环境下,如果需要配置多数据源的话,一定不要注入DataSourceAutoConfiguration.class

 

更多关于搭建Spring Cloud项目的分享,稍后会奉上。

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud配置多数据源可以使用 Spring Boot 提供的多数据源支持。下面是一个简单的示例: 1. 首先,在 `application.properties` 或 `application.yml` 中配置主数据源的信息,例如: ```yaml spring.datasource.url=jdbc:mysql://localhost:3306/main_db spring.datasource.username=root spring.datasource.password=secret spring.datasource.driver-class-name=com.mysql.jdbc.Driver ``` 2. 创建第二个数据源的配置类,例如 `SecondaryDataSourceConfig.java`: ```java @Configuration public class SecondaryDataSourceConfig { @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.secondary.datasource") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryJdbcTemplate") public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } } ``` 3. 在 `application.properties` 或 `application.yml` 中配置第二个数据源的信息,例如: ```yaml spring.secondary.datasource.url=jdbc:mysql://localhost:3306/secondary_db spring.secondary.datasource.username=root spring.secondary.datasource.password=secret spring.secondary.datasource.driver-class-name=com.mysql.jdbc.Driver ``` 4. 在需要使用第二个数据源的地方注入 `JdbcTemplate`,例如: ```java @Autowired @Qualifier("secondaryJdbcTemplate") private JdbcTemplate secondaryJdbcTemplate; ``` 这样,你就可以在 Spring Cloud配置并使用多个数据源了。请注意,上述示例是基于 Spring Boot 和 JdbcTemplate 的,你可以根据自己的需求选择其他的数据访问方式,如 MyBatis、Hibernate 等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值