GenericDAO和NoSuchBeanDefinitionException:没有唯一的bean Spring 3.0

时间:2012-06-18 11:29:29

标签: spring genericdao

我正在使用带有genericDAO的Spring 3.0。我有这个:

public interface GenericDAO<T, ID extends Serializable>
...
@Repository("genericDAO")
public class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> {
...
public interface A extends GenericDAO<Turno, Long> {
...
public interface B extends GenericDAO<TipoTurno, Long> {
...
@Repository("A")
public class AImpl extends GenericDAOImpl<TipoTurno, Long>  implements A{
...
@Repository("B")
public class BImpl extends GenericDAOImpl<TipoTurno, Long>  implements B{

但是当我尝试按照以下方式注射时:

@Autowired
A a;

我明白了:

  

预期单个匹配bean但找到3:[genericDAOImpl,A,B]

我无法理解为什么。我也尝试用

@Resource(name="A")

甚至

@Resource(type=A.class)

我也试过使用@Qualifier,但我总是得到相同的例外,看起来Spring总是在寻找GenericDao而不是特定的类。

但它仍然无效。我无法理解为什么。

有什么建议吗?

非常感谢。

2 个答案:

答案 0 :(得分:1)

我重现了您的确切错误消息然后修复了它。这正是我使用的源代码,减去包名。我建议复制它,运行它并与你的它进行区分。我注意到的一个区别是,正如问题所写,AImpl不能编译。它实现了GenericDAOImpl和GenericDAO。我将第一个通用参数更改为Turno,以使其编译。我认为这是一个错字。当我最初将所有字段设置为@Autowired时,我完全重现了您的错误。然后我添加了@Qualifier(“genericDAO”)并成功连接了所有三个。

public interface GenericDAO<T, ID extends Serializable> {}
...
@Repository("genericDAO")
public class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> {}
...
public interface A extends GenericDAO<Turno, Long> {}
...
public interface B extends GenericDAO<TipoTurno, Long> {}
...
@Repository("A")
public class AImpl extends GenericDAOImpl<Turno, Long> implements A {}
...
@Repository("B")
public class BImpl extends GenericDAOImpl<TipoTurno, Long>  implements B {}
...
public class TipoTurno {}
...
public class Turno {}
...
@Component
public class Thingy {
    @Autowired
    private A a;

    @Autowired
    private B b;

    @Autowired
    @Qualifier(value="genericDAO")
    private GenericDAO genericDao;
}
...
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("genericdao.xml");
        context.getBean(Thingy.class);
    }
}
...
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       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">
    <context:annotation-config/>
    <context:component-scan base-package="genericdao"/>
</beans>

请注意,实际的错误消息比您提供的消息长。阅读整个寻找原因的事情非常重要。 Spring喜欢5个甚至10个级别的异常堆栈跟踪。这是我收到的消息的相关子字符串:

  

无法自动装配字段:genericdao.GenericDAO genericdao.Thingy.genericDao;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有定义[genericdao.GenericDAO]类型的唯一bean:期望的单个匹配bean但找到3:[A,B,genericDAO]

它表示未自动装配的字段为Thingy.genericDao,而非Thingy.a。我强烈怀疑你的错误就是这种情况。

答案 1 :(得分:0)

@Repository("AImpl")
public class AImpl extends GenericDAOImpl<TipoTurno, Long>  implements A{
...
@Repository("BImpl")
public class BImpl extends GenericDAOImpl<TipoTurno, Long>  implements B{
...
@Resource(name = "AImpl")
A whatever; //I would normally call it aImpl

只要限定词名称匹配,你就应该好好去。该错误是由自动装配注入引起的,其中接口实现了两次。