2011-03-27 71 views
3

我目前正在使用Spring 3.0.x .. 我想知道這些結構有什麼問題, 我想管理子類而不是父類。嘗試管理多個共享公共基類的類時發生錯誤?

我有延長BaseDAO 2點孩子的DAO:

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, D extends BaseDAO<K, E>> extends BaseService<K,E,D> { 
.... 
} 

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

當嘗試一個到UserService對象注入到我的應用程序,它會拋出如下錯誤:

線程「main」中的異常 org.springfr amework.beans.factory.BeanCreationException: 創建名爲 「testEntities」的bean時出錯:注入自動裝配的 依賴關係失敗;嵌套異常 是 org.springframework.beans.factory.BeanCreationException: 無法自動裝配領域:私人 com.primetech.module.common.service.UserService com.primetech.module.purchase.app.TestEntities.userService; 嵌套異常是 org.springframework.beans.factory.BeanCreationException: 創建名爲 'userService'的bean時出錯:注入自動裝配的 依賴關係失敗;嵌套異常 是 org.springframework.beans.factory.BeanCreationException: 無法自動裝配領域:保護 com.primetech.core.parent.BaseDAO com.primetech.core.parent.BaseService.dao; 嵌套的異常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 類型的無獨特豆 [com.primetech.core.parent.BaseDAO]是 定義:預期單個匹配豆 但發現2:[userDAO的,approvalDAO ] 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1064) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(A bstractAutowireCapableBeanFactory.java:517) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 在 org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java :291) 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 在 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) 在 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425) 在 org.springframework.context.support.ClassPathXmlApplicationContext。(ClassPathXmlApplicationContext.java:139) 。在 org.springframework.context.support.ClassPathXmlApplicationContext(ClassPathXmlApplicationContext.java:93) 在 com.primetech.module.purchase.app.TestEntities.main(TestEntities.java:81) 引起: org.springframework .beans.factory.BeanCreationException: 無法自動裝入字段:private com.primetech.module.common.se rvice.UserService com.primetech.module.purchase.app.TestEntities.userService; 嵌套異常是 org.springframework.beans.factory.BeanCreationException: 創建名爲 'userService'的bean時出錯:注入自動裝配的 依賴關係失敗;嵌套異常 是 org.springframework.beans.factory.BeanCreationException: 無法自動裝配領域:保護 com.primetech.core.parent.BaseDAO com.primetech.core.parent.BaseService.dao; 嵌套的異常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 類型的無獨特豆 [com.primetech.core.parent.BaseDAO]是 定義:預期單個匹配豆 但發現2:[userDAO的,approvalDAO ] 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:507) 在 org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotation org.springframework.beans.factory.BeanCreationException:BeanPostProcessor.java:283) ... 13多個所致 錯誤創建豆與名 'userService':自動裝配 依賴注入失敗;嵌套異常 是 org.springframework.beans.factory.BeanCreationException: 無法自動裝配領域:保護 com.primetech.core.parent.BaseDAO com.primetech.core.parent.BaseService.dao; 嵌套的異常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 類型的無獨特豆 [com.primetech.core.parent.BaseDAO]是 定義:預期單個匹配豆 但發現2:[userDAO的,approvalDAO ] 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1064) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(A bstractAutowireCapableBeanFactory.java:517) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 在 org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java :291) at org.springframework。beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) 在 org.springframework.beans.factory。 support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:838) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory。 doResolveDependency(DefaultListableBeanFactory.java:780) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListab org.springframework.beans.factory.BeanCreationException:leBeanFactory.java:697) 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478) ... 15多所致: 無法自動裝入字段:受保護0​​com.primetech.core.parent.BaseDAO com.primetech.core.parent.BaseService.dao; 嵌套的異常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 類型的無獨特豆 [com.primetech.core.parent.BaseDAO]是 定義:預期單個匹配豆 但發現2:[userDAO的,approvalDAO ] 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:507) 在 org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotation org.springframework.beans.factory.NoSuchBeanDefinitionException:BeanPostProcessor.java:283) ...... 26多個所致 類型沒有唯一豆[com.primetech.core.parent.BaseDAO]是 定義:預計單匹配豆 但發現2:[userDAO的,approvalDAO] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:790) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory。 resolveDependency(DefaultListableBeanFactory.java:697) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElem ent.inject(AutowiredAnnotationBeanPostProcessor.java:478) ...... 28多個

我試圖改變這一部分,去掉@Repository註解:

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

到這一點:

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

而且事情沒有錯誤地運行,但是,此時審批DAO不再由Spring管理,並且以後不能通過@Autowired注入

關於我如何解決這個問題的任何建議?

回答

3

自動裝配僅在Spring Context中存在特定類型的實現bean時才起作用。我假設使用泛型D擴展BaseDao會導致Spring嘗試自動裝載BaseDao實例而不是UserDao和ApprovalDao的情況。由於UserDao和ApprovalDao都實現BaseDao,所以Spring上下文包含BaseDao的多個實現,並且不能決定應該使用哪一個。

春天是想告訴這對你在堆棧跟蹤

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 extends BaseEntity, D extends BaseDAO<K, E>> { 
    private final D dao; 
    protected BaseService(D dao) { 
     this.dao = dao; 
    } 
} 

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

我會繼續爲UserDao和ApprovalDao定義接口,以便依賴關係在接口上而不在實現上。 daos可能仍然有一個通用的超級接口,它們的實現可能基於BaseDao來避免不必要的重複。

在這個例子中,我定義注入道在構造函數中,因爲我認爲相同DAO實例應在整個服務的生命週期中使用和不道設置的服務就不能存在。在我看來,構造論者的觀點更好地傳達了這個契約。此外,它可能會使班級更具可測試性和可維護性。

+0

我想我愛你!在構造函數中使用注入就像魔術一樣工作!如果我可以獲得多個實現,使接口脫離DAO將會很酷。但就我而言,DAO實際上是服務的一部分,它在持續性領域負責,僅僅由於關注的分離而有區別。我認爲,只要我覺得需要提供不同的實現,我就會切換到接口。 – bertie 2011-03-27 07:03:14