当前位置: 首页 > 知识库问答 >
问题:

使用AbstractRoutingDataSource并尝试设置多个数据源时出现spring boot错误

孔鸿远
2023-03-14

我对spring boot很陌生,我正在开发一个新的应用程序,它需要能够连接到多个可用数据库中的一个。根据用户的凭据,我将确定要连接到什么数据库,因此我需要在运行时动态更改连接的能力。我发现spring的一个老博客在这里概述了一个解决方案,它提倡使用AbstractRoutingDataSource,它基于查找键将getConnection()调用路由到其他数据源。我试着仔细地跟踪这个博客,但我不断地得到以下错误。

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': 
Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'dataSource' defined in robb.referencecomponent.Application: 
Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: 
Failed to look up JNDI DataSource with name 'dev1DataSource'; nested exception is javax.naming.NoInitialContextException: 
Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial

下面是我的application.java类的代码:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
}

    @Bean
    @ConfigurationProperties(prefix="app.dev1.datasource")
    public DataSource dev1DataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix="app.dev2.datasource")
    public DataSource dev2DataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public DataSource dataSource() {
        return new RoutingDataSource();
    }

    public class RoutingDataSource extends AbstractRoutingDataSource {
        public RoutingDataSource() {
            super();
            Map<Object, Object> targetDataSources = new HashMap<>();
            targetDataSources.put(DbLocation.DEV1, "dev1DataSource");
            targetDataSources.put(DbLocation.DEV2, "dev2DataSource");
            setTargetDataSources(targetDataSources);
            setDefaultTargetDataSource(DbLocation.DEV2);
        }

        @Override
        protected Object determineCurrentLookupKey() {
           return ClientContextHolder.getDbLocation();
        }
    }

}

并在属性文件中设置数据源配置,如下所示:

app.dev1.datasource.url=jdbc:oracle:thin:@dev1_db_url
app.dev1.datasource.username=dev1
app.dev1.datasource.password=XXXXXXX
app.dev1.datasource.driver-class-name=oracle.jdbc.OracleDriver

app.dev2.datasource.url=jdbc:oracle:thin:@dev2_db_url
app.dev2.datasource.username=dev2
app.dev2.datasource.password=XXXXXXX
app.dev2.datasource.driver-class-name=oracle.jdbc.OracleDriver

我将我的一个数据源命名为'dev1DataSource',它抱怨它不能使用JNDI查找它,但是当我删除RoutingDataSource类和dataSource()bean定义并使dev1DataSource()bean@primary,我就可以很好地连接到dev1数据库。我不知道我在移植到我的应用程序时做错了什么,我知道bean是用xml建立的,但我的bean是用Java代码和注释建立的,也许是在翻译过程中犯了一些错误?

有没有人在spring boot有过使用AbstractRoutingDataSource的经验,他们遇到过这种问题?

共有1个答案

邴墨竹
2023-03-14

abstractroutingDataSource支持多种查找机制。targetDataSources类型可能会有所不同,这取决于默认为JNDI查找的DataSourceLookup。这就是您在初始化时看到noInitialContextException的原因。

您有两种解决问题的方法:

  1. 提供解析的DataSource实例,而不是dev1DataSource/dev2DataSource字符串。定义两个DataSource@bean方法,并将DataSources传递给RoutingDataSource的初始化
  2. 创建一个自己的DataSourceLookup,它从Environment中获取配置属性。自己的DataSourceLookup必须负责缓存创建的实例和应用程序关闭,这就是我推荐选项1的原因。
 类似资料:
  • 问题内容: 我尝试通过bash脚本执行此命令,但出现以下错误: 错误stacktrace: {“错误”:“ IndexPrimaryShardNotAllocatedException [[my_index]主要未分配后api]”,“状态”:409} {“错误”:“ ElasticSearchIllegalArgumentException [无法更新非动态设置[[index.analysis.f

  • springboot 配置多源数据库问题。 测试了一下springboot配置多源数据库,mysql和postgresql,yml配置如下: 运行程序,出现如下错误: …… 9:30:59:048] [INFO] - org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.prepareWebA

  • 错误为:无法获取项目:在“https://dynamodb.us-east-1.amazonaws.com”上执行“GetItem”时出错;AWS HTTP错误:客户端错误:导致响应:{"__type":"com.amazon.coral.validate#ValidationException","消息":"提供的键元素与架构不匹配"(截断...)ValidationException(客户端)

  • 我有这个问题。我正在尝试连接到数据库并推送文本用户。当我打开文件时,我只会发现很多错误。您可以进一步查看错误和我的代码。仅供参考:我的数据库在MySQLi中 警告:mysqli::\uuuu construct():php\u network\u getaddresses:getaddrinfo失败:第3行的/www/webvol9/rj/fxgnq6r66hz6x2j/my domain/pub

  • 问题内容: 这是我保存在两个变量中的两个数据框: 我正在尝试使用以下代码合并这两个: 添加how =’left’的原因是,我的ranking_df中的数据点少于标准df中的数据点。 预期的行为是这样的: 但是我得到这个错误: ValueError:您正在尝试合并object和int64列。如果要继续,则应使用pd.concat 但是我不希望使用concat,因为我想合并树而不只是添加它们。 我想到

  • 我用Java做了一个游戏。它在Eclipse中工作得非常好。 我把它导出为一个可运行的罐子。当双击它的图标时,它不会打开。所以我试着从命令行运行JAR。 在试图检索图像资源的一行代码中,我遇到了一个NullPointerException错误(正如我所说,它在Eclipse中工作得很好)。这是发生错误的代码行: 我不知道出了什么问题。这是我项目的结构: 有什么想法吗?我开始绝望了。 非常感谢你的帮