1. ホーム
  2. spring

[解決済み] 一意なビーンによる春の自動配線。Spring は一致する Bean が 1 つであると予想していたが、2 つ見つかった

2022-01-30 11:35:10

質問

私は、WebアプリケーションのためにSpringを使用していくつかのビーン(依存性注入のために)を自動配線しようとしています。 あるコントローラBeanは別のBeanを含み、そのBeanは別のBeanの集合のハッシュマップを保持します。 今のところ、マップは1つのエントリしか持っていません。 tomcatで実行し、サービスを呼び出すと、(コントローラで保持されている)2番目の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と自動配線に慣れていないので、何か基本的なことを見逃しているかもしれません。 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>

オートワイヤードコントローラとサービスビーンに関連するクラスはこちらです。

@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(); }

助けてください

解決方法は?

この問題は、SuggestionServiceタイプのBeanを@ComponentアノテーションとXMLコンフィグで作成したことに起因しています。JB Nizet氏の説明によると、@Componentで作成されたsuggestionServiceという名前のBeanと、XMLで作成されたsuggestionServiceという名前のBeanが作成されることになるそうです。

SuggestionService を @Autowired で参照すると、コントローラ内で Spring はデフォルトで "by type" を自動配線し、タイプ 'SuggestionService' の 2 つの Bean を見つけます。

次のようにすることができます。

  1. サービスから@Componentを削除し、XML経由のマッピングに依存する。

  2. SuggestionServiceをXMLから削除し、依存関係を自動配線する - indexSearchersマップを注入するためにutil:mapを使用します。

  3. Autowiredの代わりに@Resourceを使用して、その名前でBeanを選択します。

     @Resource(name="suggestionService")
     private SuggestionService service;
    
    

または

    @Resource(name="SuggestionService")
    private SuggestionService service;

3番目は汚い修正で、他の方法でBeanの衝突を解決するのがベストです。