我是Spring的新手,我正在开发一个新的应用程序,它需要能够连接到多个可用数据库中的一个.根据用户的凭据,我将确定要连接的数据库,因此我需要能够在运行时动态更改连接.我找到了一个旧的Spring博客,其中概述了这个here的解决方案,该解决方案主张使用AbstractRoutingDataSource,它基于查找键将getConnection()调用路由到其他DataSource.我试着仔细关注博客,但我一直收到以下错误.
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
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
我命名了我的一个DataSources’dev1DataSource’,它抱怨它无法使用JNDI查找它,但是当我删除RoutingDataSource类和dataSource()bean定义并使dev1DataSource()bean @Primary我能够连接到dev1数据库很好.我不确定在将旧的博客代码移植到我的应用程序中我做错了什么,我知道使用xml在示例中设置bean但是我的设置了Java代码和注释,可能在那里犯了一些错误翻译?
有没有人有在Spring引导中使用AbstractRoutingDataSource的经验并且他们遇到过这种问题?
最佳答案
AbstractRoutingDataSource支持多种查找机制. targetDataSources的值类型可能会有所不同,具体取决于默认为JNDI查找的DataSourceLookup.这就是你在初始化时看到NoInitialContextException的原因.
如何解决问题有两种选择:
>提供已解析的DataSource实例,而不是dev1DataSource / dev2DataSource字符串.您定义了两个DataSource @Bean方法,并将DataSources传递给RoutingDataSource的初始化.
>创建一个自己的DataSourceLookup,从Environment中获取配置属性.自己的DataSourceLookup必须负责缓存创建的实例和应用程序关闭,这就是我推荐选项1的原因.