[英]Bean must be of 'javax.sql.DataSource' type, exception with Java Spring
[英]Using 2 beans of the same type: javax.sql.DataSource in Spring
我正在开发一个基于 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;
}
问题是在启动时我得到了这个:
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
主要是因为它们都继承自javax.sql.DataSource。 解决这个问题的最佳方法是什么?
编辑:
现在我已将它们声明如下:
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;
}
并得到了这个例外:
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
其他类引用这些 bean 如下:
公共类 MetadataProcessorImpl 实现 MetadataProcessor {
@Autowired
@Qualifier("metadataDataSource")
BoneCPDataSource metadataDataSource;
@Controller 公共类 HiveController {
@Autowired
@Qualifier("hiveDataSource")
BasicDataSource hiveDataSource;
如第67.2节配置两个数据源中所述,将光束之一设置为 @Primary
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-two-datasources
使用@Bean
时为您的 bean 指定不同的名称:
@Bean(name="bonecpDS")
public BoneCPDataSource metadataDataSource() {
//...
}
@Bean(name="hiveDS")
public BasicDataSource hiveDataSource() {
//...
}
然后,在注入 bean 时,使用@Qualifier
并指定 bean 的名称:
@Component
public class FooComponent {
@Autowired
@Qualifier("bonecpDS")
DataSource boneCPDataSource;
}
如果您想同时使用两个数据源并且它们不是主要和次要的,您应该在@SpringBootApplication(excludes = {DataSourceAutoConfiguration.class})
注释的应用程序上禁用DataSourceAutoConfiguration
。
由于DataSourceAutoConfiguration
将初始化DataSourceInitializer
类。 DataSourceInitializer
类中的 init 方法需要获取DataSource
。 当有多个DataSource
,系统会因获取哪个DataSource
而感到困惑。
@SpringBootApplication(excludes = {DataSourceAutoConfiguration.class})
表示系统在运行应用程序时不会加载DataSourceAutoConfiguration.class
。
我遇到了类似的问题。 添加@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class})
并添加了手动配置。 有效!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.