使用 2 个相同类型的 bean:Spring 中的 javax.sql.DataSource
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23687369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using 2 beans of the same type: javax.sql.DataSource in Spring
提问by DilTeam
I am developing a Spring Boot based application in which I would like to create 2 beans: One will point to 'Oracle' database; the other will point to Hive. I've declared them as follows:
我正在开发一个基于 Spring Boot 的应用程序,我想在其中创建 2 个 bean:一个指向“Oracle”数据库;另一个将指向 Hive。我已将它们声明如下:
public @Bean
BoneCPDataSource metadataDataSource() {
BoneCPDataSource boneCPDataSource = new BoneCPDataSource();
boneCPDataSource.setDriverClass(getDriver());
boneCPDataSource.setJdbcUrl(getJdbcUrl());
boneCPDataSource.setUser(getUser());
boneCPDataSource.setPassword(getPassword());
boneCPDataSource.setMaxConnectionsPerPartition(5);
boneCPDataSource.setPartitionCount(5);
return boneCPDataSource;
}
public @Bean
BasicDataSource hiveDataSource() {
BasicDataSource basicDataSource = new BasicDataSource();
// Note: In a separate command window, use port forwarding like this:
//
// ssh -L 127.0.0.1:9996:<server>:<port> -l <userid> <server>
//
// and then login as the generic user.
basicDataSource.setDriverClassName("org.apache.hadoop.hive.jdbc.HiveDriver");
basicDataSource.setUrl("jdbc:hive://127.0.0.1:9996:10000/mytable");
return basicDataSource;
}
Problem is at the startup I am getting this:
问题是在启动时我得到了这个:
Exception in thread "main"
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name
'org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration':
Injection of autowired dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private javax.sql.DataSource
org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration.dataSource;
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: metadataDataSource,hiveDataSource
Mainly because both of them inherit from javax.sql.DataSource. What's the best way to fix this?
主要是因为它们都继承自javax.sql.DataSource。解决这个问题的最佳方法是什么?
EDIT:
编辑:
Now I've declared them as follows:
现在我已将它们声明如下:
public @Bean (name="metadataDataSource")
BoneCPDataSource metadataDataSource() {
BoneCPDataSource boneCPDataSource = new BoneCPDataSource();
boneCPDataSource.setDriverClass(getDriver());
boneCPDataSource.setJdbcUrl(getJdbcUrl());
boneCPDataSource.setUser(getUser());
boneCPDataSource.setPassword(getPassword());
boneCPDataSource.setMaxConnectionsPerPartition(5);
boneCPDataSource.setPartitionCount(5);
return boneCPDataSource;
}
public @Bean (name="hiveDataSource")
BasicDataSource hiveDataSource() {
BasicDataSource basicDataSource = new BasicDataSource();
// Note: In a separate command window, use port forwarding like this:
//
// ssh -L 127.0.0.1:9996:<server>:<port> -l <userid> <server>
//
// and then login as the generic user.
basicDataSource.setDriverClassName("org.apache.hadoop.hive.jdbc.HiveDriver");
basicDataSource.setUrl("jdbc:hive://127.0.0.1:9996:10000/mytable");
return basicDataSource;
}
And got this exception:
并得到了这个例外:
Exception in thread "main"
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name
'org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration':
Injection of autowired dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private javax.sql.DataSource
org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration.dataSource;
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: metadataDataSource,hiveDataSource
The other classes are referring to these beans as follows:
其他类引用这些 bean 如下:
public class MetadataProcessorImpl implements MetadataProcessor {
公共类 MetadataProcessorImpl 实现 MetadataProcessor {
@Autowired
@Qualifier("metadataDataSource")
BoneCPDataSource metadataDataSource;
@Controller public class HiveController {
@Controller 公共类 HiveController {
@Autowired
@Qualifier("hiveDataSource")
BasicDataSource hiveDataSource;
采纳答案by Luiggi Mendoza
Give different names to your beans when using @Bean
:
使用时为您的 bean 赋予不同的名称@Bean
:
@Bean(name="bonecpDS")
public BoneCPDataSource metadataDataSource() {
//...
}
@Bean(name="hiveDS")
public BasicDataSource hiveDataSource() {
//...
}
Then, when injecting the bean, use @Qualifier
and specify the name of the bean:
然后,在注入 bean 时,使用@Qualifier
并指定 bean 的名称:
@Component
public class FooComponent {
@Autowired
@Qualifier("bonecpDS")
DataSource boneCPDataSource;
}
回答by Danilo
Set one of the beam as @Primary as described in the section 67.2 Configure Two DataSources
如第67.2节配置两个数据源中所述,将光束之一设置为 @Primary
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-two-datasources
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-two-datasources
回答by Tina Zhang
If you want to use two data sources at the same time and they are not primary and secondary, you should disable DataSourceAutoConfiguration
on your application annotated by @SpringBootApplication(excludes = {DataSourceAutoConfiguration.class})
.
如果您想同时使用两个数据源并且它们不是主要的和次要的,您应该DataSourceAutoConfiguration
在由@SpringBootApplication(excludes = {DataSourceAutoConfiguration.class})
.
Since the DataSourceAutoConfiguration
will init the DataSourceInitializer
class. The init method in DataSourceInitializer
class needs to get DataSource
. When there is more than one DataSource
, the system gets confused by getting which DataSource
.
由于DataSourceAutoConfiguration
将初始化DataSourceInitializer
该类。类中的 init 方法DataSourceInitializer
需要获取DataSource
. 当有多个时DataSource
,系统会因获取 which 而感到困惑DataSource
。
@SpringBootApplication(excludes = {DataSourceAutoConfiguration.class})
means that system won't load the DataSourceAutoConfiguration.class
when run the application.
@SpringBootApplication(excludes = {DataSourceAutoConfiguration.class})
意味着系统不会DataSourceAutoConfiguration.class
在运行应用程序时加载。
回答by Mahesh Vemula
I faced similar issue. Added @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class})
我遇到了类似的问题。添加@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class})
and added manual configuration. It worked!
并添加了手动配置。有效!