Je développe une application basée sur Spring Boot dans laquelle j’aimerais créer 2 beans: l’un pointera vers la firebase database ‘Oracle’; l’autre pointera vers Hive. Je les ai déclarés comme suit:
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:: -l // // 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; }
Le problème est au démarrage, je reçois ceci:
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
Principalement parce que les deux héritent de javax.sql.DataSource. Quelle est la meilleure façon de résoudre ce problème?
MODIFIER:
Maintenant, je les ai déclarés comme suit:
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:: -l // // 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; }
Et j’ai cette 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
Les autres classes font référence à ces haricots comme suit:
Classe publique MetadataProcessorImpl implémente MetadataProcessor {
@Autowired @Qualifier("metadataDataSource") BoneCPDataSource metadataDataSource;
@Controller public class HiveController {
@Autowired @Qualifier("hiveDataSource") BasicDataSource hiveDataSource;
Donnez des noms différents à vos haricots lorsque vous utilisez @Bean
:
@Bean(name="bonecpDS") public BoneCPDataSource metadataDataSource() { //... } @Bean(name="hiveDS") public BasicDataSource hiveDataSource() { //... }
Ensuite, lors de l’injection du haricot, utilisez @Qualifier
et spécifiez le nom du haricot:
@Component public class FooComponent { @Autowired @Qualifier("bonecpDS") DataSource boneCPDataSource; }
Définissez l’un des faisceaux sur @Primary comme décrit dans la section 67.2 Configuration de deux sources de données
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-two-datasources