代码之家  ›  专栏  ›  技术社区  ›  Peders

Spring3DI使用通用DAO接口

  •  7
  • Peders  · 技术社区  · 16 年前

    我试图在我的通用Dao界面中使用@Autowired annotation,如下所示:

    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 />
    

    这只能部分起作用,因为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...
    }
    

    可悲的是,这并没有成为例外:

    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是可能的。任何帮助都将不胜感激:)

    2 回复  |  直到 16 年前
        1
  •  2
  •   Peders    16 年前

    好的,我想我已经找到了一个相当合理的解决方案。解决这个问题的一种方法是为我的域模型中的每个实体创建接口和实现(正如埃斯彭在前面的回答中指出的)。现在,考虑数百个实体和数百个实现。那感觉不对,是吗?

    我放弃了强类型子接口,而是使用泛型接口:

    @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>
    

    因此,基本上我无法让纯通用自动布线工作,但这个解决方案对我来说很有效(至少目前是这样):)

        2
  •  0
  •   Espen    16 年前

    可以自动连接任意数量的bean。

    但是,当您使用类型自动连接时,它只能是每个接口的一个bean。您的错误消息表示,给定接口的Spring容器中没有可用的bean。

    解决方案:

    缺少的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 . @可配置 与AspectJ一起使用,而不是您想要的。你必须使用 @Component 或者是它的一种特殊化 @服务 .

    还记得把所有的弹簧组件都放在电脑里 com.organization.sample 包以使Spring容器能够找到它们。

    我希望这有帮助!