복붙노트

[SPRING] 동일한 유형의 2 개의 bean 사용 : Spring의 javax.sql.DataSource

SPRING

동일한 유형의 2 개의 bean 사용 : Spring의 javax.sql.DataSource

저는 Spring Bean 기반의 어플리케이션을 개발 중입니다.이 어플리케이션에서는 2 개의 bean을 만들고 싶습니다. 하나는 'Oracle'데이터베이스를 가리킬 것입니다. 다른 하나는 하이브를 가리킬 것입니다. 저는 다음과 같이 선언했습니다 :

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

다른 클래스는 다음과 같이이 빈을 참조합니다.

공용 클래스 MetadataProcessorImpl은 MetadataProcessor {

@Autowired
@Qualifier("metadataDataSource")
BoneCPDataSource metadataDataSource;

@제어 장치 공용 클래스 HiveController {

@Autowired
@Qualifier("hiveDataSource")
BasicDataSource hiveDataSource;

해결법

  1. ==============================

    1.@Bean을 사용할 때 빈에 다른 이름을 지정하십시오.

    @Bean을 사용할 때 빈에 다른 이름을 지정하십시오.

    @Bean(name="bonecpDS")
    public BoneCPDataSource metadataDataSource() {
        //...
    }
    
    @Bean(name="hiveDS")
    public BasicDataSource hiveDataSource() {
        //...
    }
    

    그런 다음 빈을 주입 할 때 @Qualifier를 사용하고 빈의 이름을 지정하십시오.

    @Component
    public class FooComponent {
        @Autowired
        @Qualifier("bonecpDS")
        DataSource boneCPDataSource;
    }
    
  2. ==============================

    2.하나의 빔을 @Primary로 설정하십시오. 67.2 섹션에서 설명한 것처럼 두 개의 데이터 소스 구성

    하나의 빔을 @Primary로 설정하십시오. 67.2 섹션에서 설명한 것처럼 두 개의 데이터 소스 구성

    http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-two-datasources

  3. ==============================

    3.동시에 두 개의 데이터 소스를 사용하려는 경우 기본 및 보조 클래스가 아닌 경우 @SpringBootApplication (excludes = {DataSourceAutoConfiguration.class})으로 주석을 추가 한 응용 프로그램에서 DataSourceAutoConfiguration을 비활성화해야합니다.

    동시에 두 개의 데이터 소스를 사용하려는 경우 기본 및 보조 클래스가 아닌 경우 @SpringBootApplication (excludes = {DataSourceAutoConfiguration.class})으로 주석을 추가 한 응용 프로그램에서 DataSourceAutoConfiguration을 비활성화해야합니다.

    DataSourceAutoConfiguration은 DataSourceInitializer 클래스를 초기화 할 것이기 때문에. DataSourceInitializer 클래스의 init 메소드는 DataSource를 가져와야합니다. 하나 이상의 DataSource가있는 경우 시스템은 어떤 DataSource를 가져 와서 혼란 스럽습니다.

    @SpringBootApplication (excludes = {DataSourceAutoConfiguration.class})은 응용 프로그램을 실행할 때 시스템이 DataSourceAutoConfiguration.class를로드하지 않음을 의미합니다.

  4. from https://stackoverflow.com/questions/23687369/using-2-beans-of-the-same-type-javax-sql-datasource-in-spring by cc-by-sa and MIT license