微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

尝试管理共享公共基类的多个类时出现Spring错误?

我目前正在使用Spring 3.0.x ..
我想知道这些结构有什么问题,
我想管理子类而不是父类的地方.

我有2个子DAO扩展了BaseDAO:

public abstract class BaseDAO<K,E> {
....
}

@Repository
public class UserDAO extends BaseDAO<String,User> {
....
}

@Repository
public class ApprovalDAO extends BaseDAO<String,Approval> {
....
}

我有这样的服务,并具有这样的层次结构:

public abstract class BaseService<K,E extends BaseEntity,D extends BaseDAO<K,E>> {
    @Autowired
    protected D dao;
....
}

public abstract class BaseCommonService<K,E extends BaseCommonEntity,E>> extends BaseService<K,E,D> {
....
}

@Service
public class UserService extends BaseCommonService<String,User,UserDAO> {
....
}

当尝试将userservice对象注入我的应用程序时,它会引发如下错误

Exception in thread “main”
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
‘testEntities’: Injection of autowired
dependencies Failed; nested exception
is
org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private
com.primetech.module.common.service.UserService
com.primetech.module.purchase.app.TestEntities.userService;
nested exception is
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
‘userService’: Injection of autowired
dependencies Failed; nested exception
is
org.springframework.beans.factory.BeanCreationException:
Could not autowire field: protected
com.primetech.core.parent.BaseDAO
com.primetech.core.parent.BaseService.dao;
nested exception is
org.springframework.beans.factory.NoSuchBeanDeFinitionException:
No unique bean of type
[com.primetech.core.parent.BaseDAO] is
defined: expected single matching bean
but found 2: [userDAO,approvalDAO]
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcesspropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
at
org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.populateBean(AbstractAutowireCapablebeanfactory.java:1064)
at
org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.doCreateBean(AbstractAutowireCapablebeanfactory.java:517)
at
org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:456)
at
org.springframework.beans.factory.support.Abstractbeanfactory$1.getobject(Abstractbeanfactory.java:291)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at
org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:288)
at
org.springframework.beans.factory.support.Abstractbeanfactory.getBean(Abstractbeanfactory.java:190)
at
org.springframework.beans.factory.support.DefaultListablebeanfactory.preInstantiateSingletons(DefaultListablebeanfactory.java:574)
at
org.springframework.context.support.AbstractApplicationContext.finishbeanfactoryInitialization(AbstractApplicationContext.java:895)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at
org.springframework.context.support.ClasspathXmlApplicationContext.(ClasspathXmlApplicationContext.java:139)
at
org.springframework.context.support.ClasspathXmlApplicationContext.(ClasspathXmlApplicationContext.java:93)
at
com.primetech.module.purchase.app.TestEntities.main(TestEntities.java:81)
Caused by:
org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private
com.primetech.module.common.service.UserService
com.primetech.module.purchase.app.TestEntities.userService;
nested exception is
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
‘userService’: Injection of autowired
dependencies Failed; nested exception
is
org.springframework.beans.factory.BeanCreationException:
Could not autowire field: protected
com.primetech.core.parent.BaseDAO
com.primetech.core.parent.BaseService.dao;
nested exception is
org.springframework.beans.factory.NoSuchBeanDeFinitionException:
No unique bean of type
[com.primetech.core.parent.BaseDAO] is
defined: expected single matching bean
but found 2: [userDAO,approvalDAO]
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:507)
at
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcesspropertyValues(AutowiredAnnotationBeanPostProcessor.java:283)
… 13 more Caused by:
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
‘userService’: Injection of autowired
dependencies Failed; nested exception
is
org.springframework.beans.factory.BeanCreationException:
Could not autowire field: protected
com.primetech.core.parent.BaseDAO
com.primetech.core.parent.BaseService.dao;
nested exception is
org.springframework.beans.factory.NoSuchBeanDeFinitionException:
No unique bean of type
[com.primetech.core.parent.BaseDAO] is
defined: expected single matching bean
but found 2: [userDAO,approvalDAO]
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcesspropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
at
org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.populateBean(AbstractAutowireCapablebeanfactory.java:1064)
at
org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.doCreateBean(AbstractAutowireCapablebeanfactory.java:517)
at
org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:456)
at
org.springframework.beans.factory.support.Abstractbeanfactory$1.getobject(Abstractbeanfactory.java:291)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at
org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:288)
at
org.springframework.beans.factory.support.Abstractbeanfactory.getBean(Abstractbeanfactory.java:190)
at
org.springframework.beans.factory.support.DefaultListablebeanfactory.findAutowireCandidates(DefaultListablebeanfactory.java:838)
at
org.springframework.beans.factory.support.DefaultListablebeanfactory.doResolveDependency(DefaultListablebeanfactory.java:780)
at
org.springframework.beans.factory.support.DefaultListablebeanfactory.resolveDependency(DefaultListablebeanfactory.java:697)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
… 15 more Caused by:
org.springframework.beans.factory.BeanCreationException:
Could not autowire field: protected
com.primetech.core.parent.BaseDAO
com.primetech.core.parent.BaseService.dao;
nested exception is
org.springframework.beans.factory.NoSuchBeanDeFinitionException:
No unique bean of type
[com.primetech.core.parent.BaseDAO] is
defined: expected single matching bean
but found 2: [userDAO,approvalDAO]
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:507)
at
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcesspropertyValues(AutowiredAnnotationBeanPostProcessor.java:283)
… 26 more Caused by:
org.springframework.beans.factory.NoSuchBeanDeFinitionException:
No unique bean of type
[com.primetech.core.parent.BaseDAO] is
defined: expected single matching bean
but found 2: [userDAO,approvalDAO]
at
org.springframework.beans.factory.support.DefaultListablebeanfactory.doResolveDependency(DefaultListablebeanfactory.java:790)
at
org.springframework.beans.factory.support.DefaultListablebeanfactory.resolveDependency(DefaultListablebeanfactory.java:697)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
… 28 more

我尝试更改此部分,删除@Repository批注:

@Repository
public class ApprovalDAO extends BaseDAO<String,Approval> {
....
}

到这个:

public class ApprovalDAO extends BaseDAO<String,Approval> {
....
}

事情运行没有错误,但随后,rovalingDAO不再由spring管理,以后无法由@Autowired注入

关于如何解决此问题的任何建议?

最佳答案
仅当Spring Context中存在一个特定类型的实现bean时,自动装配才起作用.我假设使用通用D扩展BaseDao会导致Spring尝试自动装配BaseDao实例而不是UserDao和ApprovalDao的情况.由于UserDao和ApprovalDao都实现了BaseDao,因此Spring上下文包含BaseDao的多个实现,并且无法决定应使用哪个实现.

Spring试图在堆栈跟踪中告诉您

org.springframework.beans.factory.NoSuchBeanDeFinitionException: 
__No unique bean of type__ [com.primetech.core.parent.BaseDAO] is defined:
expected single matching bean but found 2: [userDAO,approvalDAO]

您可以尝试通过在具体服务中使用实际的dao类型定义dao来测试此情况,例如

public abstract class BaseService<K,E>> {
   private final D dao;
   protected BaseService(D dao) {
      this.dao = dao;
   } 
}

public class UserService extends BaseService<K,UserDao<K,User>> {
   @Autowired
   public UserService(UserDao dao) {
     super(dao);
   }
}

我将继续为UserDao和ApprovalDao定义接口,以使依赖关系依赖于接口而不是实现.这些dao可能仍然具有公共的超级接口,并且其实现可能基于BaseDao以避免不必要的重复.

在该示例中,我已在构造函数中定义了注入的Dao,因为我假设在服务的整个生命周期中都应使用相同的dao实例,并且如果没有dao集合,则该服务将不存在.我认为,构造函数参数可以更好地传达此合同.此外,这可能会使该类更具可测试性和可维护性.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐