2016-12-19 17 views
3

활성 스프링 웹 앱을 스프링 부트 (1.4.2)로 마이그레이션 중입니다.스프링 부트가 @Qualifier 주석을 무시합니다.

빈은 @ImportResource로로드 될 때 XML로 정의됩니다.

내가 시작하는 콩의 4 개가 동일한 객체 BasicDataSource의 인스턴스입니다.

로드 할 스프링을 지정하려면 각 ID를 설정하고 @Qualifier를 사용하여 올바른 bean을 변수에 바인드하십시오.

그러나 그 봄이 내 @Qualifier를 무시하고 던지고 것 같다

" '는 javax.sql.DataSource'가능한 유형의 어떠한 자격 콩 : DataSource1, DataSource2, DataSource3, DataSource4 : 4 예상 하나의 일치 콩을하지만 발견"을

PS - @Qualifier가있는 클래스는 추상 클래스이고 인스턴스화에 실패한 클래스는 확장 클래스이지만 @Qualifier는 @Inherited를 가지고 있습니다.

주요 XML

<beans 
    xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:task="http://www.springframework.org/schema/task" 
xmlns:cache="http://www.springframework.org/schema/cache" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xmlns:p="http://www.springframework.org/schema/p" 
xmlns:util="http://www.springframework.org/schema/util" 
xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.2.xsd 
    http://www.springframework.org/schema/jee 
    http://www.springframework.org/schema/jee/spring-jee-3.2.xsd 
    http://www.springframework.org/schema/task 
    http://www.springframework.org/schema/task/spring-task-3.2.xsd 
    http://www.springframework.org/schema/cache 
    http://www.springframework.org/schema/cache/spring-cache-3.2.xsd 
    http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring 
    http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd"> 

<context:load-time-weaver aspectj-weaving="on"/> 
<cache:annotation-driven mode="aspectj"/> 
<context:property-override location="file:/app/config/dataSourceOverride.cfg"/> 
<context:annotation-config /> 

<bean id="DataSource1" class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close"> 
    <property name="userId" value="4" /> 
</bean> 

<bean id="DataSource2" class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close"> 
    <property name="userId" value="3" /> 
</bean> 

<bean id="DataSource3" class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close"> 
    <property name="userId" value="2" /> 
</bean> 

<bean id="DataSource4" class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close"> 
    <property name="userId" value="1" /> 
</bean> 

봄 부팅 응용 프로그램

package com.app; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.ImportResource; 


@SpringBootApplication 
@EnableAutoConfiguration 
@ComponentScan("com.app") 
@ImportResource("com/app/startup/spring.xml") 
public class SpringBootServer { 

    public static void main(String[] args) { 
     SpringApplication.run(SpringBootServer.class, args); 

    } 
} 

추상 클래스

public abstract class GenericDao { 

    public GenericDao() { 

    } 

    private Logger logger = LoggerFactory.getLogger(GenericDao.class); 

    @Autowired 
    @Qualifier("DataSource1") 
    protected BasicDataSource dataSource1Impl; 

    @Autowired 
    @Qualifier("DataSource2") 
    protected BasicDataSource dataSource2Impl; 

    @Autowired 
    @Qualifier("DataSource3") 
    protected BasicDataSource dataSource3Impl; 

    @Autowired 
    @Qualifier("DataSource4") 
    protected BasicDataSource dataSource4Impl; 
} 

솔리드 CALSS

@Component("widgetsDao") 
public class WidgetsDao extends GenericDao { 

##Some methods## 

} 

예외 아마도 봄 내 @Qualifier 주석을 무시하도록 만들 수있는 어떤

*************************** 
APPLICATION FAILED TO START 
*************************** 

Description: 

Field dataSource1Impl in com.app.dal.GenericDao required a single bean, but 4 were found: 
    - DataSource1: defined in class path resource [com/app/startup/app-spring.xml] 
    - DataSource2: defined in class path resource [com/app/startup/app-spring.xml] 
    - DataSource3: defined in class path resource [com/app/startup/app-spring.xml] 
    - DataSource4: defined in class path resource [com/app/startup/app-spring.xml] 


Action: 

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed 

?

고맙습니다.

+0

XML 구성에 한정자가 없습니다. –

+0

id가 한정자 이름 역할을합니다 – Ronco

+0

이것이 왜 작동하지 않는 지 모르겠지만 bean 이름이 변수 이름과 일치하면 한정자가 필요하지 않습니다. '@Autowired BasicDataSource datasource4'는'datasource4'라는 이름의 bean으로 연결될 것입니다. – slim

답변

2

여러 개의 데이터 소스를 사용할 때 동일한 오류가 발생했으며 데이터 소스 bean 중 하나를 "기본"으로 설정하면 문제가 해결 된 것처럼 보였으므로 @Qualifier 주석을 사용하여 올바른 bean을 autowire 할 수있었습니다.

스프링 부트 설명서 here은 여러 데이터 소스를 사용할 때 데이터 소스 bean 중 하나가 기본이어야한다고 말합니다.

Java에서 @Bean 주석을 사용하여 bean을 구성 했으므로 @Primary 주석을 사용하여 하나의 기본 항목을 작성했습니다. 하지만 XML로 구성하는 경우 XML의 요소에 XML로 Bean을 구성하는 데 사용할 수있는 선택적 "기본"속성이있는 것처럼 보입니다.

0

제이크 (Jake)에 따르면 적어도이 오류를 없애려면 @Primary 주석을 추가해야합니다. 플러스 :

외부 파일에서 데이터 소스 속성을 가져 오는 경우 기본 데이터 소스의 속성 (예 :url, user, pass 등)을 spring.datasource으로 바꾸어서 Spring Boot의 기본 내부 데이터 소스 인 Derby, HSQL 등을 사용자 설정에 우선합니다.