我有一个测试用例依赖于'ticketDao',如下所示:
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Qualifier;
public class LfnSaleCancellationIntegrationTest extends BaseIntegrationTest {
//@Resource(name = "baseTicketDao")
private BaseTicketDao ticketDao;
....
public void setTicketDao(@Qualifier("baseTicketDao") BaseTicketDao ticketDao) {
this.ticketDao = ticketDao;
}
}
和BaseIntegrationTest从Spring测试框架的AbstractJpaTests扩展,Spring是v3.0.5
运行此测试用例时,我遇到了类似的异常:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type [com.mpos.lottery.te.gamespec.sale.dao.BaseTicketDao]
is defined: expected single matching bean but found 2:
[baseTicketDao, extraballTicketDao]
我的项目已经发展了很长时间,事实上当我第一次遇到这个异常时,@ Qualifier解决了它。直到今天这个项目发生了很大变化,但我真的不知道为什么@Qaulifier和@Resource不再工作了。
如果我删除'ticketDao'的依赖关系,测试用例将通过。我想知道弹簧配置是否有一些变化导致这个异常?或者......我用google搜索了很多,但似乎没有其他人遇到过这样的问题,请给出你的意见,非常感谢!
答案 0 :(得分:1)
您正在使用AbstractJPATests
,它是旧的Spring测试框架和AbstractDependencyInjectionSpringContextTests
的(间接)子类的一部分。默认情况下,注入不是基于注释的,但它会发现设置器和字段,并尝试按类型注入。建议切换到更新的基于注释的测试,有关详细信息,请参阅spring文档。
作为解决方法尝试更改自动装配模式。在测试构造函数中将其作为this.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME)
调用,将您的字段重命名为baseTicketDao并删除setter。
答案 1 :(得分:0)
我知道原因。在我的新项目中,有一个上下文声明:spring-configuration文件中的component-scan,它默认会注册4个BeanPostProcessors:
在我的旧项目中,只注册了默认的BeanPostProcessor(internalAutoProxyCreator)。我的理解是AutowiredAnnotationBeanPostProcessor将始终按类型连接。无论如何,如果删除上下文:组件扫描,我的测试用例现在可以通过。
实际上我现在已经将我的所有测试用例迁移到spring测试上下文框架,并且必须声明上下文:component-scan,否则将忽略@Autowired,@ Resource等注释,并且你会得到很多NullPointerException那些自动注入的依赖项。
注意:<context:annotation-config/>
也将注册这4个BeanPostProcessors。