GenericDAO 和 NoSuchBeanDefinitionException:没有唯一的 bean Spring 3.0
Posted
技术标签:
【中文标题】GenericDAO 和 NoSuchBeanDefinitionException:没有唯一的 bean Spring 3.0【英文标题】:GenericDAO and NoSuchBeanDefinitionException: No unique bean Spring 3.0 【发布时间】:2012-06-20 08:45:40 【问题描述】:我正在使用带有 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 而不是特定的类。
但它仍然无法正常工作。我不明白为什么。
有什么建议吗?
非常感谢。
【问题讨论】:
您确定在所有三种情况下都收到相同的错误消息吗?我可以看到您如何在 @Autowired 案例中获得“预期的单个匹配 bean”消息,但绝对不是在 @Resource(name="A") 案例中。您是否可能同时注释了 getter 和成员变量? 非常感谢您的帮助。我已经加倍检查它来回答你,是的,当我使用 @Resource(name="specific_name") 我得到 org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [xxx.model.entities.dao. GenericDAO] 被定义:预期的单个匹配 bean,但找到了 3:[genericDAO,A,B]。关于您的问题,我没有对 getter 进行注释。 @CalamarBicefalo 限定符名称与接口相同,这是错误的 @NimChimpsky,我更改了限定符名称,而不是 A 我设置了猫,而不是 B 我设置了狗,这一次它再次失败:预期单个匹配 bean 但找到 3:[genericDAO,猫狗]。我试过用@Resource(name="cat") 来做。 删除 @Repository("genericDAO") 注释。您不需要将其定义为 bean。 【参考方案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
。我强烈怀疑您的错误也是这种情况。
【讨论】:
它做到了。事实上,问题在于我试图在没有限定条件的情况下注入“genericDAO”。但这让我抓狂,因为我希望通过特定的注射来解决它。非常感谢@John Watts,非常有帮助。我不能投票赞成你的答案,因为我没有名声:'( 不客气。感谢您接受答案。我希望有关春季异常的评论会有所帮助。尽管它们通常包含必要的信息,但它可能会在大量原因中丢失。 仔细阅读异常跟踪是我发现错误的方式,所以是的,你的评论真的很有帮助。【参考方案2】:@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
只要限定符名称匹配,您就可以开始了。该错误是由自动装配注入引起的,其中接口被实现了两次。
【讨论】:
谢谢 NimChimpsky,但如前所述,我在同时使用 @Resource(name= "specific_name") 和 @Resource(type=specific_class.class) 时遇到完全相同的异常 @CalamarBicefalo 看看我改变了什么。您的接口名称与限定符相同,这会导致问题。按照我概述的方式进行操作很好。 正如我上次回复中所说,它仍然无法正常工作。但无论如何,非常感谢@NimChimpsky。我用实现名称和随机名称都试过了。 @CalamarBicefalo 我根本无法复制它。您正在使用限定符名称进行注入? GenericDAO 在 AImpl 上“实现了两次”——这会在自动装配时引起问题。 @CalamarBicefalo 您需要删除自动连线注入。并且只使用限定符注入。并期待重构,它有点复杂的 api 设计以上是关于GenericDAO 和 NoSuchBeanDefinitionException:没有唯一的 bean Spring 3.0的主要内容,如果未能解决你的问题,请参考以下文章
用于开发 GenericDao 的最佳 Spring API
如何在 GenericDao 中检索常用值(IpAddress、TenantId)?