복붙노트

[SPRING] 고유 한 bean을 가진 스프링 autowiring : 봄 예상되는 단일 일치하는 bean은 찾았지만 2

SPRING

고유 한 bean을 가진 스프링 autowiring : 봄 예상되는 단일 일치하는 bean은 찾았지만 2

나는 웹 애플리케이션을 위해 Spring을 사용하여 (의존성 삽입을 위해) 몇몇 bean을 autowire하려고 시도하고있다. 하나의 컨트롤러 bean은 또 다른 bean을 포함하는데,이 bean은 다른 bean 세트의 해시 맵을 보유합니다. 현재지도에는 하나의 항목 만 있습니다. 내가 바람둥이에서 실행하고 서비스를 호출하면 오류가 두 번째 콩 (컨트롤러에서 개최되는) 고유하지 않습니다

No unique bean of type [com.hp.it.km.search.web.suggestion.SuggestionService] is defined: expected single matching bean but found 2: [suggestionService, SuggestionService]

콩을 두 번 정의하는 부분을 볼 수는 없지만 Spring과 autowiring에 익숙하지 않아 뭔가 근본적인 것을 놓칠 수 있습니다. XML 및 아래에 나열된 2 개 클래스의 소스 코드 ...

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"     xmlns:context="http://www.springframework.org/schema/context"     xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<context:component-scan base-package="com.hp.it.km.search.web.suggestion" />
<mvc:annotation-driven />
<context:annotation-config />

<bean id="SuggestionController" class="com.hp.it.km.search.web.suggestion.SuggestionController">
    <property name="service">
        <ref bean="SuggestionService" />
    </property>
</bean>

<bean id="SuggestionService" class="com.hp.it.km.search.web.suggestion.SuggestionService">
    <property name="indexSearchers"> 
         <map>
            <entry key="KMSearcher"> <ref bean="KMSearcherBean"></ref></entry>
        </map>
    </property>
</bean>

<bean id="KMSearcherBean" class="com.hp.it.km.search.web.suggestion.SuggestionIndexSearcher">
      <constructor-arg index="0" value="KMSearcher" />
      <constructor-arg index="1" value="C://dev//workspace//search-restful-webapp//src//main//resources//indexes//keyword" />
</bean>

autowired 컨트롤러 및 서비스 빈과 관련된 클래스는 여기에 있습니다 ...

@Controller
public class SuggestionController {
private SuggestionService service;

@Autowired
public void setService(SuggestionService service) {
    this.service = service;
}

public SuggestionService getService() {
    return service;
}

과...

@Component
public class SuggestionService {

private Map<String, IndexSearcher> indexSearchers = new HashMap<String,      IndexSearcher>();

@Autowired
public void setIndexSearchers(Map<String, IndexSearcher> indexSearchers) {
    this.indexSearchers = indexSearchers;
}

    public SuggestionService() {
    super(); }

도와주세요!

해결법

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

    1.@Component 주석과 XML 설정을 통해 생성 된 SuggestionService 유형의 빈을 가지고 있기 때문에 문제가 발생합니다. JB Nizet이 설명했듯이, 이것은 @Component를 통해 생성 된 'suggestionService'라는 이름의 빈을 만들고, XML을 통해 생성 된 'SuggestionService'라는 이름을 가진 빈을 생성하게 될 것입니다.

    @Component 주석과 XML 설정을 통해 생성 된 SuggestionService 유형의 빈을 가지고 있기 때문에 문제가 발생합니다. JB Nizet이 설명했듯이, 이것은 @Component를 통해 생성 된 'suggestionService'라는 이름의 빈을 만들고, XML을 통해 생성 된 'SuggestionService'라는 이름을 가진 빈을 생성하게 될 것입니다.

    컨트롤러에서 @Autowired가 제공하는 SuggestionService를 참조하면 Spring은 기본적으로 "유형별"autowires를 사용하여 'SuggestionService'유형의 두 빈을 찾습니다.

    당신은 다음을 할 수 있습니다.

    또는

        @Resource("SuggestionService")
        private SuggestionService service;
    

    세 번째는 더티 픽스이며 다른 방법으로 빈 충돌을 해결하는 것이 가장 좋습니다.

  2. ==============================

    2.하나의 클래스에 자동적으로 같은 클래스의 빈을 두 개 가지고 있다면 @Qualifier (@ Authiring @Qualifier 예제) @Qualifier를 사용해야한다.

    하나의 클래스에 자동적으로 같은 클래스의 빈을 두 개 가지고 있다면 @Qualifier (@ Authiring @Qualifier 예제) @Qualifier를 사용해야한다.

    하지만 귀하의 문제는 잘못된 Java 구문에서 온 것 같습니다.

    개체는 소문자로 시작해야합니다.

    SuggestionService suggestion;
    

    당신의 세터는 소문자로 시작해야하며 객체 이름은 대문자로해야합니다.

    public void setSuggestion(final Suggestion suggestion) {
        this.suggestion = suggestion;
    }
    
  3. ==============================

    3.저에게 그것은 동일한 인터페이스를 구현하는 두 개의 빈이있는 경우입니다. 하나는 원래 콩과 상충되는 단원 테스트를 위 한 가짜 금지 조치였습니다. 우리가 사용하면

    저에게 그것은 동일한 인터페이스를 구현하는 두 개의 빈이있는 경우입니다. 하나는 원래 콩과 상충되는 단원 테스트를 위 한 가짜 금지 조치였습니다. 우리가 사용하면

    , 여전히 suggestionService를 참조합니다. 그래서 @component를 제거하고

    문제를 해결 한

  4. ==============================

    4.내가 잘못하지 않는다면, @Component로 선언 된 빈의 기본 빈 이름은 그 클래스의 이름이며 첫 번째 문자는 소문자이다. 이것은

    내가 잘못하지 않는다면, @Component로 선언 된 빈의 기본 빈 이름은 그 클래스의 이름이며 첫 번째 문자는 소문자이다. 이것은

    @Component
    public class SuggestionService {
    

    SuggestionService 유형의 bean을 선언하고 suggestionService 이름을 선언합니다. 그것은

    @Component("suggestionService")
    public class SuggestionService {
    

    또는

    <bean id="suggestionService" .../>
    

    동일한 유형의 다른 bean을 XML에서 다른 이름으로 재정의하고 있습니다.

    <bean id="SuggestionService" class="com.hp.it.km.search.web.suggestion.SuggestionService">
        ...
    </bean>
    

    그러므로 주석에서 Bean의 이름을 SuggestionService로 지정하거나 XML에서 ID suggestionService를 사용하십시오 ( 요소를 수정하거나 필요하지 않으므로이를 삭제하는 것을 잊지 마십시오) . 이 경우 XML 정의가 주석 정의를 대체합니다.

  5. from https://stackoverflow.com/questions/8414287/spring-autowiring-with-unique-beans-spring-expected-single-matching-bean-but-fo by cc-by-sa and MIT license