如何使用接口声明DAO变量,并在Spring框架中放入具体的实现?

问题描述 投票:0回答:2

我正在研究如何将Spring框架与Hibernate集成,对此我有一些疑问。

我开发了一个运行良好的个人示例,但我不确定该项目的架构。

所以我有一个名为 PersonDAO 的接口,其中我声明了我将在 DAO 中执行的 CRUD 操作

然后我通过实现先前接口的类 PersonDAOImpl 创建了该接口的具体实现。

然后我创建了以下主类来测试我的 dao 对象:

package org.andrea.myexample.HibernateOnSpring;

    import org.andrea.myexample.HibernateOnSpring.dao.PersonDAOImpl;
    import org.andrea.myexample.HibernateOnSpring.entity.Person;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class App {
   
    public static void main( String[] args ){
        
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        System.out.println("Contesto recuperato: " + context);
        
        Person persona1 = new Person();
        
        persona1.setFirstname("Pippo");
        persona1.setLastname("Blabla");
        persona1.setPid(1);
        
        System.out.println("Creato persona1: " + persona1);
        
        PersonDAOImpl dao = (PersonDAOImpl) context.getBean("personDAOImpl");
        
        System.out.println("Creato dao object: " + dao);
        
        dao.addPerson(persona1);
        
        System.out.println("persona1 salvata nel database");
        
    }
}

DAO 运行良好,我的对象正确地保存在我的数据库中,但我有以下架构疑问:如果我不使用接口,为什么还要有一个接口?

最后,这样我就无法拥有接口,直接使用具体类了...

我认为,从建筑角度来看,这太糟糕了......

我尝试更改我的 App.java 类并尝试以这种方式使用 DAO 对象:

PersonDAO dao = (PersonDAO) context.getBean("personDAOImpl");

但不工作...

在本教程中:http://viralpatel.net/blogs/spring3-mvc-hibernate-maven-tutorial-eclipse-example/

还有另一种情况,真正使用该接口,其中有一个 ContactServiceImpl 类,其中我使用 @Autowired 注释声明了 ContactDAO 变量:

@Autowired
private ContactDAO contactDAO;

ContactDAO是一个DAO接口,但是Spring自动装配一个对象,它是它的实现的一个实例ContactDAOImpl(使用@Repository注释)

因此,使用 **@Autowired 注释,在这段代码中我可以使用接口声明一个变量,但在此变量中放入对其具体实现的引用!

在我的项目中,我不使用注释bean配置机制,但我使用XML配置机制...但我认为在这种情况下我也可以做类似的事情...

我的项目 XML 配置文件我已经像这样声明了我的 bean:

<bean id="personDAOImpl" class="org.andrea.myexample.HibernateOnSpring.dao.PersonDAOImpl" >
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

如何将我的 dao 变量声明为接口并放入其具体实现? (仍然使用XML配置)

这是我使用时遇到的堆栈跟踪错误

    PersonDAO dao = (PersonDAO) context.getBean("personDAOImpl");

在我的 App.Java 测试类中

信息:使用 HibernateSessionFactory 的 DataSource [org.apache.commons.dbcp.BasicDataSource@7363c839] 进行 HibernateTransactionManager 恢复竞赛:org.springframework.context.support.ClassPathXmlApplicationContext@591f5ff9:启动日期 [2013 年 2 月 23 日星期六 11:42:25 CET];线程“main”中上下文层次结构的根异常 创建角色1:org.andrea.myexample.HibernateOnSpring.entity.Person@23653628 java.lang.ClassCastException: org.andrea.myexample.HibernateOnSpring.dao.PersonDAOImpl$$EnhancerByCGLIB$$d46b3a86 无法转换为 org.andrea.myexample.HibernateOnSpring.dao.PersonDAO 在 org.andrea.myexample.HibernateOnSpring.App.main(App.java:27)

谢谢

java spring hibernate spring-mvc annotations
2个回答
1
投票

接口和具体实现的本质是保持多态性。在测试环境中,您可以使用不同的具体实现但相同的接口,而在开发模式下,可以将另一个实现放入 xml 配置中。您可以轻松地交换 xml 配置,而无需更改 java 代码,例如从开发环境切换到测试环境,或者其他测试人员会使用您相同的代码但具有不同的 xml 配置。

如果您打算直接使用 xml 中的实现,那么您将失去多态性的能力,并且如果必须切换到不同的实现,则需要更改 java 代码。

你的PersonDAOImpl必须实现PersonDAO,比如

public class PersonDAOImpl implements PersonDAO

Xml 配置仅用于跨应用程序的依赖注入或单例 bean 实例,它与保留多态性没有任何关系。你所要做的就是遵循java的接口实现。


0
投票

PersonDAOImpl 的代码在哪里?它必须实现 PersonDAO 接口

© www.soinside.com 2019 - 2024. All rights reserved.