Spring for webappを使用して、いくつかのBean(依存性注入用)を自動配線しようとしています。 1つのコントローラー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]
Beanを2回定義している場所がわかりませんが、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>
自動配線されたコントローラーとサービス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(); }
助けてください!
問題は、@ ComponentアノテーションおよびXML configを通じてSuggestionServiceタイプのBeanが作成されているためです。 JB Nizetが説明したように、これは@Componentを介して作成された 'suggestionService'という名前のBeanと、XMLを介して作成された 'SuggestionService'という名前のBeanの作成につながります。
コントローラーでSuggestionServiceを@Autowiredで参照すると、Springはデフォルトで「タイプ別」に自動配線し、「SuggestionService」タイプの2つのBeanを見つけます。
次のことができます
名前でBeanを選択するには、@ Autowiredの代わりに@Resourceを使用します。
@Resource("suggestionService")
private SuggestionService service;
または
@Resource("SuggestionService")
private SuggestionService service;
3番目は汚い修正であり、他の方法でBeanの競合を解決するのが最善です。
同じクラスの2つのBeanが1つのクラスに自動配線されている場合は、@Qualifier
( スプリング自動配線@修飾子の例 )。
しかし、あなたの問題は間違ったJava Syntax。
オブジェクトは小文字で始める必要があります
SuggestionService suggestion;
セッターも小文字で始まり、オブジェクト名は大文字である必要があります
public void setSuggestion(final Suggestion suggestion) {
this.suggestion = suggestion;
}
間違っていなければ、@ Componentで宣言されたBeanのデフォルトのBean名は、クラスの最初の文字が小文字のクラスの名前です。この意味は
@Component
public class SuggestionService {
タイプSuggestionService
、および名前suggestionService
のBeanを宣言します。それは同等です
@Component("suggestionService")
public class SuggestionService {
または
<bean id="suggestionService" .../>
XMLで、同じタイプの別のBeanを別の名前で再定義しています。
<bean id="SuggestionService" class="com.hp.it.km.search.web.suggestion.SuggestionService">
...
</bean>
したがって、アノテーションでBeanの名前をSuggestionService
に指定するか、XMLでID suggestionService
を使用します(<ref>
要素も変更することを忘れないでください。または、削除する必要はありません)。この場合、XML定義は注釈定義をオーバーライドします。
私にとっては、2つのBeanが同じインターフェースを実装している場合でした。 1つは、元のBeanと競合する単体テストのための偽の禁止でした。使用する場合
@component( "suggestionServicefake")
、suggestionServiceで引き続き参照します。だから私は@componentを削除し、使用しただけ
@Qualifier( "suggestionServicefake")
問題を解決しました