我正在研究如何将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)
谢谢
接口和具体实现的本质是保持多态性。在测试环境中,您可以使用不同的具体实现但相同的接口,而在开发模式下,可以将另一个实现放入 xml 配置中。您可以轻松地交换 xml 配置,而无需更改 java 代码,例如从开发环境切换到测试环境,或者其他测试人员会使用您相同的代码但具有不同的 xml 配置。
如果您打算直接使用 xml 中的实现,那么您将失去多态性的能力,并且如果必须切换到不同的实现,则需要更改 java 代码。
你的PersonDAOImpl必须实现PersonDAO,比如
public class PersonDAOImpl implements PersonDAO
Xml 配置仅用于跨应用程序的依赖注入或单例 bean 实例,它与保留多态性没有任何关系。你所要做的就是遵循java的接口实现。
PersonDAOImpl 的代码在哪里?它必须实现 PersonDAO 接口