使用dubbo對外暴露介面,實現類同時實現兩個介面後 @Autowire失敗,提示expected single matching bean but found 2解決方案
阿新 • • 發佈:2019-01-28
當使用dubbo對外暴露介面時,為了方便繼承和實現底層方法,另一方面專門對外提供一套介面方法,這時介面實現類同時實現了兩個介面:
@Service("ICentAccountInfoService")
public class CentAccountInfoServiceImpl
extends AbstractPageService<IBaseDAO<CentAccountInfo>, CentAccountInfo>
implements
ICentAccountInfoService<IBaseDAO<CentAccountInfo >,CentAccountInfo>,
CentAccountInfoServiceAPI {
@Autowired
private CentAccountInfoDAO centAccountInfoDAO;
@Override
public IBaseDAO<CentAccountInfo> getDao() {
return null;
}
//實現 ICentAccountInfoService 方法
public int insert(CentAccountInfo cent){
System.out.println("==== insert in!");
int result = centAccountInfoDAO.insert(cent);
return result;
}
//實現對外業務介面 CentAccountInfoServiceAPI 方法
@Override
public void showMembers() {
System.out.println("==== show members!!" );
}
}
dubbo對外暴露服務是這樣處理的:
<dubbo:service interface="cn.qtone.xxt.api.CentAccountInfoServiceAPI"
ref="CentAccountInfoServiceAPI" executes="100" timeout="600000" retries="0" />
<bean id="CentAccountInfoServiceAPI" class="cn.qtone.xxt.cent.service.Impl.CentAccountInfoServiceImpl" />
對外暴露的介面:
public interface CentAccountInfoServiceAPI
{
public void showMembers();
}
現在用Junit測試看看:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:applicationContext.xml")
public class CentAccountInfoServiceTest{
@Autowired
// @Qualifier("ICentAccountInfoService")
private CentAccountInfoServiceImpl centAccountInfoService;
@Test
public void test(){
//showcase
// Assert.assertEquals(1, centAccountInfoService.findAll().size());
CentAccountInfo cent = new CentAccountInfo();
cent.setPhone("13377777777");
cent.setCreateTime(new Date());
Assert.assertEquals(1, centAccountInfoService.insert(cent)); //impl實現的介面 ICentAccountInfoService 中的方法
centAccountInfoService.showMembers(); //impl實現的介面 CentAccountInfoServiceAPI 中的方法
}
}
但測試結果報錯,提示:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private cn.qtone.xxt.cent.service.Impl.CentAccountInfoServiceImpl cn.qtone.xxt.test.service.CentAccountInfoServiceTest.centAccountInfoService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [cn.qtone.xxt.cent.service.Impl.CentAccountInfoServiceImpl] is defined: expected single matching bean but found 2: [ICentAccountInfoService, CentAccountInfoServiceAPI]
...(省略)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [cn.qtone.xxt.cent.service.Impl.CentAccountInfoServiceImpl] is defined: expected single matching bean but found 2: [ICentAccountInfoService, CentAccountInfoServiceAPI]
... 31 more
查了下這個問題,發現在使用Spring框架中@Autowired標籤時預設情況下使用 @Autowired 註釋進行自動注入時,Spring 容器中匹配的候選 Bean 數目必須有且僅有一個。當找不到一個匹配的 Bean 時,Spring 容器將拋BeanCreationException 異常,並指出必須至少擁有一個匹配的 Bean。
這時的解決辦法就是:
通過 @Qualifier 註釋指定注入 Bean 的名稱,這樣歧義就消除了。
只需要加一行程式碼,這個問題迎刃而解:
@Autowired
@Qualifier("ICentAccountInfoService")
private CentAccountInfoServiceImpl centAccountInfoService;
測試結果:
驗證ok!