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