7

我試圖使用@Autowired註解與我的通用DAO接口是這樣的:春3 DI通用DAO接口

public interface DaoContainer<E extends DomainObject> { 
    public int numberOfItems(); 
    // Other methods omitted for brevity 
} 

我在下列方式使用該接口在我的控制器:

@Configurable 
public class HelloWorld { 
    @Autowired 
    private DaoContainer<Notification> notificationContainer; 

    @Autowired 
    private DaoContainer<User> userContainer; 

    // Implementation omitted for brevity 
} 

我已經配置了我的應用程序上下文中使用以下配置

<context:spring-configured /> 
<context:component-scan base-package="com.organization.sample"> 
<context:exclude-filter expression="org.springframework.stereotype.Controller" 
    type="annotation" /> 
</context:component-scan> 
<tx:annotation-driven /> 

這隻有partiall y,因爲Spring創建並注入了我的DaoContainer的一個實例,即DaoContainer。換句話說,如果我問了userContainer.numberOfItems();我得到

我試圖使用強類型接口來標記的正確實施這樣notificationContainer.numberOfItems()的數量:

public interface NotificationContainer extends DaoContainer<Notification> { } 
public interface UserContainer extends DaoContainer<User> { } 

然後使用這些接口是這樣的:

@Configurable 
public class HelloWorld { 
    @Autowired 
    private NotificationContainer notificationContainer; 
    @Autowired 
    private UserContainer userContainer; 
    // Implementation omitted... 
} 

可悲的是這未能BeanCreationException:

org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.organization.sample.dao.NotificationContainer com.organization.sample.HelloWorld.notificationContainer; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.organization.sample.NotificationContainer] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 

現在,我有點困惑,我應該如何繼續或甚至可能使用多個Dao。任何幫助將不勝感激:)

+0

我沒有看到您的接口的任何實現類。有多少人,他們看起來像什麼? – skaffman 2010-05-17 07:38:01

+0

我沒有明確的接口實現,因爲我希望我可以使用通用的dao類(即DaoContainer )。我可以創建顯式的實現(正如Espen在他的回答中指出的那樣)。這只是不合理,因爲我試圖儘可能多地利用Java泛型。但是,我確實有DaoContainerImpl 。 – Peders 2010-05-19 05:30:17

+0

也許http://stackoverflow.com/questions/502994/spring-ioc-and-generic-interface-type/511417#511417是一個解決方案 – 2010-08-18 09:38:45

回答

0

這是可能的autowire儘可能多的豆,只要你喜歡。

但是,當您按類型使用自動裝配時,它只能是每個界面的bean之一。你的錯誤消息說你在給定接口的Spring容器中沒有可用的bean。

A液:

你丟失的DAO實現:

@Repository 
public class NotificationContainerImpl implements NotificationContainer {} 

@Repository 
public class UserContainerImpl implements UserContainer {} 

服務類:

@Service 
public class HelloWorld { 
    @Autowired 
    private NotificationContainer notificationContainer; 
    @Autowired 
    private UserContainer userContainer; 
    // Implementation omitted... 
} 

我更換了@Configurable批註與@Service@Configurable與AspectJ一起使用,不是你想要的。您必須使用@Component或其專門化,如@Service

還記得在你的com.organization.sample包中包含所有的Spring組件,以使Spring容器能夠找到它們。

我希望這有助於!

2

好吧,我想我找到了一個相當合理的解決方案,這個難題。處理這個問題的一種方法是爲我的域模型中的每個實體創建接口和實現(正如Espen在他之前的答案中指出的那樣)。現在,考慮擁有數百個實體和數百個實現。那感覺不對,會嗎?

我堅決丟棄類型的子接口,我使用的是通用的接口,而不是:

@Service // Using @Service annotation instead @Configurable as Espen pointed out 
public class HelloWorld { 
    @Autowired 
    private DaoContainer<Notification> notificationContainer; 

    @Autowired 
    private DaoContainer<User> userContainer; 

    // Implementation omitted 
} 

我DaoContainer接口的實現會是這個樣子:

@Repository 
public class DaoContainerImpl<E extends DomainObject> implements DaoContainer<E> { 

    // This is something I need in my application logic 
    protected Class<E> type; 

    public int getNumberOfItems() { 
     // implementation omitted 
    } 
    // getters and setters for fields omitted 

} 

最後應用上下文:

<context:spring-configured /> 
<context:component-scan base-package="com.organization.sample"> 
<context:exclude-filter expression="org.springframework.stereotype.Controller" 
    type="annotation" /> 
</context:component-scan> 

<bean class="com.organization.sample.dao.DaoContainerImpl" id="userContainer"> 
    <property name="type" value="com.organization.sample.domain.DiaryUser" /> 
</bean> 
<bean class="com.organization.sample.dao.DaoContainerImpl" id="notificationContainer"> 
    <property name="type" value="com.organization.sample.domain.DiaryNotification" /> 
</bean> 

所以基本上我無法得到純粹的通用自動工作,但這個解決方案適用於我(至少現在):)

+0

我知道這是一個老問題,但你的解決方案非常類似於使用標記接口,如http://stackoverflow.com/questions/502994/spring-ioc-and-generic-interface-type/503011#503011中所述。我猜想它會出現個人喜好來污染Spring配置文件或Java源代碼樹。 – 2010-09-14 20:40:10