问题描述
做了一个spring+hibernate的例子xml是这样的<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--SessionFactory Transaction******************************************--><bean id="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><property name="configLocation"value="classpath:hibernate.cfg.xml"></property></bean><bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="initial*" propagation="REQUIRED" /><tx:method name="add*" propagation="REQUIRED" /><tx:method name="update*" propagation="REQUIRED" /><tx:method name="delete*" propagation="REQUIRED" /><tx:method name="*" propagation="SUPPORTS" read-only="true" /></tx:attributes></tx:advice><aop:config><aop:advisor pointcut="execution(* com.service.*Service.*(..))"advice-ref="txAdvice" /></aop:config> <!--SessionFactory Transaction End**************************************--><!--DAO Begin***********************************************************--><bean id="productDAO" class="com.dao.ProductDAO"><property name="sessionFactory" ref="sessionFactory"></property></bean><bean id="categoryDAO" class="com.dao.CategoryDAO"><property name="sessionFactory" ref="sessionFactory"></property></bean><!--DAO End*************************************************************--><!--Service*************************************************************--><bean id="initialService" class="com.service.InitialServiceImpl"><property name="categoryDAO" ref="categoryDAO"></property><property name="productDAO" ref="productDAO"></property></bean><!--Service End*********************************************************--></beans>ProductDAO的代码:package com.dao;import java.util.List;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.LockMode;import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.criterion.Example;import com.domain.Product;public class ProductDAO {private static final Log log = LogFactory.getLog(ProductDAO.class);// property constantspublic static final String NAME = "name";public static final String DESCRIPTION = "description";public static final String PRICE = "price";/***************************************************************** */private SessionFactory sessionFactory;public void setSessionFactory(SessionFactory sessionFactory) {this.sessionFactory = sessionFactory;}private Session getSession() {return sessionFactory.getCurrentSession();}/***************************************************************** */public void save(Product transientInstance) {log.debug("saving Product instance");try {getSession().save(transientInstance);log.debug("save successful");} catch (RuntimeException re) {log.error("save failed", re);throw re;}}public void delete(Product persistentInstance) {log.debug("deleting Product instance");try {getSession().delete(persistentInstance);log.debug("delete successful");} catch (RuntimeException re) {log.error("delete failed", re);throw re;}}public Product findById(java.lang.Integer id) {log.debug("getting Product instance with id: " + id);try {Product instance = (Product) getSession().get("com.domain.Product",id);return instance;} catch (RuntimeException re) {log.error("get failed", re);throw re;}}@SuppressWarnings("unchecked")public List<Product> findByExample(Product instance) {log.debug("finding Product instance by example");try {List<Product> results = getSession().createCriteria("com.domain.Product").add(Example.create(instance)).list();log.debug("find by example successful, result size: "+ results.size());return results;} catch (RuntimeException re) {log.error("find by example failed", re);throw re;}}@SuppressWarnings("unchecked")public List<Product> findByProperty(String propertyName, Object value) {log.debug("finding Product instance with property: " + propertyName+ ", value: " + value);try {String queryString = "from Product as model where model."+ propertyName + "= ?";Query queryObject = getSession().createQuery(queryString);queryObject.setParameter(0, value);return queryObject.list();} catch (RuntimeException re) {log.error("find by property name failed", re);throw re;}}public List<Product> findByName(Object name) {return findByProperty(NAME, name);}public List<Product> findByDescription(Object description) {return findByProperty(DESCRIPTION, description);}public List<Product> findByPrice(Object price) {return findByProperty(PRICE, price);}@SuppressWarnings("unchecked")public List<Product> findAll() {log.debug("finding all Product instances");try {String queryString = "from Product";Query queryObject = getSession().createQuery(queryString);return queryObject.list();} catch (RuntimeException re) {log.error("find all failed", re);throw re;}}public Product merge(Product detachedInstance) {log.debug("merging Product instance");try {Product result = (Product) getSession().merge(detachedInstance);log.debug("merge successful");return result;} catch (RuntimeException re) {log.error("merge failed", re);throw re;}}public void attachDirty(Product instance) {log.debug("attaching dirty Product instance");try {getSession().saveOrUpdate(instance);log.debug("attach successful");} catch (RuntimeException re) {log.error("attach failed", re);throw re;}}public void attachClean(Product instance) {log.debug("attaching clean Product instance");try {getSession().lock(instance, LockMode.NONE);log.debug("attach successful");} catch (RuntimeException re) {log.error("attach failed", re);throw re;}}}问题是xml文件中Spring给productDAO注入的bean类型明明是org.springframework.orm.hibernate3.LocalSessionFactoryBean;这个类型根本没有getCurrentSession的方法。而productDAO中的sessionFactory是org.hibernate.SessionFactory,这中间的类型是怎么转换的啊?试了一下往数据库保存是成功的,就是想不通这个类型的转换,我看LocalSessionFactoryBean也没有实现SessionFactory这个接口啊?难道是LocalSessionFactoryBean的getObject()方法?
解决方案
引用难道是LocalSessionFactoryBean的getObject()方法? 正是如此!LocalSessionFactoryBean实现了org.springframework.beans.factory.FactoryBean接口, spring在装配的时候, 如果发现实现了org.springframework.beans.factory.FactoryBean接口, 就会使用FactoryBean#getObject() 方法返回的对象装配,具体的可以看下文档.如果你想拿到LocalSessionFactoryBean实例, 在id前面加个'&'就可以了,在你的配置文件中BeanFactory.getBean('&sessionFactory')拿到的就是LocalSessionFactoryBean的实例.
解决方案二:
楼上说的非常正确,这就是要搞清BeanFactory和FactoryBean的区别