关于Spring的LocalSessionFactoryBean的问题

做了一个spring+hibernate的例子
xml是这样的[code="xml"]<?xml version="1.0" encoding="UTF-8"?>
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.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://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*********************************************************-->

[/code]
ProductDAO的代码:
[code="java"]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 constants
public 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;
    }
}

}[/code]
问题是xml文件中Spring给productDAO注入的bean类型明明是org.springframework.orm.hibernate3.LocalSessionFactoryBean;
这个类型根本没有getCurrentSession的方法。
而productDAO中的sessionFactory是org.hibernate.SessionFactory,这中间的类型是怎么转换的啊?
试了一下往数据库保存是成功的,就是想不通这个类型的转换,我看LocalSessionFactoryBean也没有实现SessionFactory这个接口啊?
难道是LocalSessionFactoryBean的getObject()方法?

2个回答

[quote]难道是LocalSessionFactoryBean的getObject()方法? [/quote]

正是如此!LocalSessionFactoryBean实现了org.springframework.beans.factory.FactoryBean接口, spring在装配的时候, 如果发现实现了org.springframework.beans.factory.FactoryBean接口, 就会使用FactoryBean#getObject() 方法返回的对象装配,具体的可以看下文档.
如果你想拿到LocalSessionFactoryBean实例, 在id前面加个'&'就可以了,在你的配置文件中BeanFactory.getBean('&sessionFactory')拿到的就是LocalSessionFactoryBean的实例.

:idea: 楼上说的非常正确,这就是要搞清BeanFactory和FactoryBean的区别

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐