ITKeyword,专注技术干货聚合推荐

注册 | 登录

Spring框架学习【HibernateTemplate对Hibernate的封装】

zhixiang2010 分享于 2014-01-21

推荐:Spring整合的Hibernate的框架中,HibernateTemplate、SessionFactory和Session之间的关系

Session Session 也就是 Hibernate中一个事务操作的缓存对象,Spring封装Hibernate也就是封装对Session的操作,简化对session的操作。 SessionFactory SessionFa

2020腾讯云共同战“疫”,助力复工(优惠前所未有!4核8G,5M带宽 1684元/3年),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1053

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

1.Spring中,不提供具体的ORM实现,而只是为应用提供对ORM产品的集成环境和使用平台,Spring将Hibernate的会话工厂通过IoC容器管理起来,并且将数据源注入,同时Spring为Hibernate提供了更上层的API封装,方便应用调用,本文通过分析相应源码了解Spring对Hibernate支持的实现。 2.AbstractSessionFactoryBean管理Hibernate会话工厂: 使用过Hibernate的人都知道,Hibernate的SessionFactory(会话工厂)是Hibernate的基础,SessionFactory管理Hibernate的相关配置和映射资源,Spring中通过AbstractSessionFactoryBean抽象类来管理Hibernate的会话工厂,AbstractSessionFactoryBean实现Spring的工厂Bean(FactoryBean)接口,因此AbstractSessionFactoryBean是一个Spring的工厂Bean,即Spring管理Hibernate的IoC容器,AbstractSessionFactoryBean的源码如下: [java] view plaincopyprint? public abstract class AbstractSessionFactoryBean

implements FactoryBean<SessionFactory>, InitializingBean, DisposableBean, PersistenceExceptionTranslator {

protected final Log logger = LogFactory.getLog(getClass());

//数据源

private DataSource dataSource;

//Hibernate会话使用Spring事务管理器包装的数据源

private boolean useTransactionAwareDataSource = false;

//从Hibernate会话工厂中获取的当前会话是否暴露给Spring事务来包装

private boolean exposeTransactionAwareSessionFactory = true;

//Hibernate SQL相关异常转换器

private SQLExceptionTranslator jdbcExceptionTranslator;

//Hibernate会话工厂

private SessionFactory sessionFactory;

//为会话工厂设置数据源,如果设置,则覆盖Hibernate配置文件中的数据源设置

public void setDataSource(DataSource dataSource) {

this.dataSource = dataSource;

}

public DataSource getDataSource() {

return this.dataSource;

}

//设置Hibernate会话工厂是否使用Spring事务(jdbc事务)包装的数据源,

//true,则使用Spring的jdbc事务;false,则使用Hibernate事务或者JTA

public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) {

this.useTransactionAwareDataSource = useTransactionAwareDataSource;

}

protected boolean isUseTransactionAwareDataSource() {

return this.useTransactionAwareDataSource;

}

//为通过Hibernate会话工厂getCurrentSession()方法获得的当前会话设置

//是否使用Spring会话包装

public void setExposeTransactionAwareSessionFactory(boolean exposeTransactionAwareSessionFactory) {

this.exposeTransactionAwareSessionFactory = exposeTransactionAwareSessionFactory;

}

protected boolean isExposeTransactionAwareSessionFactory() {

return this.exposeTransactionAwareSessionFactory;

}

//为Hibernate会话工厂设置JDBC异常转换器,当Hibernate产生的任何由jdbc异常

//引起的SQL异常时,使用jdbc异常覆盖Hibernate默认的SQL方言(Dialect)异常

public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) {

this.jdbcExceptionTranslator = jdbcExceptionTranslator;

}

//创建Hibernate会话工厂,IoC容器初始化回调方法

public void afterPropertiesSet() throws Exception {

//委托模式,调用AbstractSessionFactoryBean子类//LocalSessionFactoryBean实现的方法

SessionFactory rawSf = buildSessionFactory();

//如果需要,将给定的会话工厂使用代理包装

this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf);

//钩子方法,Hibernate会话工厂创建成功后,应用自定义处理

afterSessionFactoryCreation();

}

//如果有需要,将给定的Hibernate会话工厂用代理封装

protected SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) {

return rawSf;

}

//应用从Spring管理Hibernate会话工厂的IoC容器中获取SessionFactory

protected final SessionFactory getSessionFactory() {

if (this.sessionFactory == null) {

throw new IllegalStateException("SessionFactory not initialized yet");

}

return this.sessionFactory;

}

//当Spring管理Hibernate会话工厂的IoC容器关闭时关闭所创建的会话工厂

public void destroy() throws HibernateException {

logger.info("Closing Hibernate SessionFactory");

try {

beforeSessionFactoryDestruction();

}

finally {

this.sessionFactory.close();

}

}

//获取单态模式的Hibernate会话工厂

public SessionFactory getObject() {

return this.sessionFactory;

}

//获取Hibernate会话工厂的对象类型

public Class<? extends SessionFactory> getObjectType() {

return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class);

}

public boolean isSingleton() {

return true;

}

//转换异常

public DataAccessException translateExceptionIfPossible(RuntimeException ex) {

//如果异常时Hibernate异常类型

if (ex instanceof HibernateException) {

//转换Hibernate异常

return convertHibernateAccessException((HibernateException) ex);

}

//如果不是Hibernate异常,则返回null

return null;

}

//转换Hibernate异常

protected DataAccessException convertHibernateAccessException(HibernateException ex) {

//如果Hibernate会话工厂设置了Jdbc异常转换器,且给定的异常是jdbc异常类型,

//则使用设置的jdbc异常转换器转换给定的Hibernate异常

if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) {

JDBCException jdbcEx = (JDBCException) ex;

return this.jdbcExceptionTranslator.translate(

"Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException());

}

//如果Hibernate会话工厂没有设置jdbc异常转换器,或者给定异常不是jdbc异常

//类型,则使用Hibernate默认的异常转换器转换

return SessionFactoryUtils.convertHibernateAccessException(ex);

}

//创建Hibernate会话工厂

protected abstract SessionFactory buildSessionFactory() throws Exception;

//钩子方法,Hibernate会话工厂成功创建后操作处理

protected void afterSessionFactoryCreation() throws Exception {

}

//钩子方法,Hibernate会话工厂关闭前操作处理

protected void beforeSessionFactoryDestruction() {

}

}

public abstract class AbstractSessionFactoryBean implements FactoryBean<SessionFactory>, InitializingBean, DisposableBean, PersistenceExceptionTranslator { protected final Log logger = LogFactory.getLog(getClass()); //数据源 private DataSource dataSource;//Hibernate会话使用Spring事务管理器包装的数据源 private boolean useTransactionAwareDataSource = false; //从Hibernate会话工厂中获取的当前会话是否暴露给Spring事务来包装 private boolean exposeTransactionAwareSessionFactory = true; //Hibernate SQL相关异常转换器 private SQLExceptionTranslator jdbcExceptionTranslator; //Hibernate会话工厂 private SessionFactory sessionFactory; //为会话工厂设置数据源,如果设置,则覆盖Hibernate配置文件中的数据源设置 public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public DataSource getDataSource() { return this.dataSource; }//设置Hibernate会话工厂是否使用Spring事务(jdbc事务)包装的数据源,//true,则使用Spring的jdbc事务;false,则使用Hibernate事务或者JTA public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) { this.useTransactionAwareDataSource = useTransactionAwareDataSource; } protected boolean isUseTransactionAwareDataSource() { return this.useTransactionAwareDataSource; } //为通过Hibernate会话工厂getCurrentSession()方法获得的当前会话设置//是否使用Spring会话包装 public void setExposeTransactionAwareSessionFactory(boolean exposeTransactionAwareSessionFactory) { this.exposeTransactionAwareSessionFactory = exposeTransactionAwareSessionFactory; } protected boolean isExposeTransactionAwareSessionFactory() { return this.exposeTransactionAwareSessionFactory; } //为Hibernate会话工厂设置JDBC异常转换器,当Hibernate产生的任何由jdbc异常//引起的SQL异常时,使用jdbc异常覆盖Hibernate默认的SQL方言(Dialect)异常 public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { this.jdbcExceptionTranslator = jdbcExceptionTranslator; }//创建Hibernate会话工厂,IoC容器初始化回调方法 public void afterPropertiesSet() throws Exception {//委托模式,调用AbstractSessionFactoryBean子类//LocalSessionFactoryBean实现的方法 SessionFactory rawSf = buildSessionFactory(); //如果需要,将给定的会话工厂使用代理包装 this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf); //钩子方法,Hibernate会话工厂创建成功后,应用自定义处理 afterSessionFactoryCreation(); } //如果有需要,将给定的Hibernate会话工厂用代理封装 protected SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) { return rawSf; } //应用从Spring管理Hibernate会话工厂的IoC容器中获取SessionFactory protected final SessionFactory getSessionFactory() { if (this.sessionFactory == null) { throw new IllegalStateException("SessionFactory not initialized yet"); } return this.sessionFactory; } //当Spring管理Hibernate会话工厂的IoC容器关闭时关闭所创建的会话工厂 public void destroy() throws HibernateException { logger.info("Closing Hibernate SessionFactory"); try { beforeSessionFactoryDestruction(); } finally { this.sessionFactory.close(); } }//获取单态模式的Hibernate会话工厂 public SessionFactory getObject() { return this.sessionFactory; } //获取Hibernate会话工厂的对象类型 public Class<? extends SessionFactory> getObjectType() { return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class); } public boolean isSingleton() { return true; }//转换异常 public DataAccessException translateExceptionIfPossible(RuntimeException ex) { //如果异常时Hibernate异常类型 if (ex instanceof HibernateException) { //转换Hibernate异常 return convertHibernateAccessException((HibernateException) ex); } //如果不是Hibernate异常,则返回null return null; }//转换Hibernate异常 protected DataAccessException convertHibernateAccessException(HibernateException ex) { //如果Hibernate会话工厂设置了Jdbc异常转换器,且给定的异常是jdbc异常类型, //则使用设置的jdbc异常转换器转换给定的Hibernate异常 if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) { JDBCException jdbcEx = (JDBCException) ex; return this.jdbcExceptionTranslator.translate( "Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException()); }//如果Hibernate会话工厂没有设置jdbc异常转换器,或者给定异常不是jdbc异常//类型,则使用Hibernate默认的异常转换器转换 return SessionFactoryUtils.convertHibernateAccessException(ex); }//创建Hibernate会话工厂 protected abstract SessionFactory buildSessionFactory() throws Exception; //钩子方法,Hibernate会话工厂成功创建后操作处理 protected void afterSessionFactoryCreation() throws Exception { } //钩子方法,Hibernate会话工厂关闭前操作处理 protected void beforeSessionFactoryDestruction() { }} 通过分析Spring对Hibernate会话工厂管理的IoC容器AbstractSessionFactoryBean的源码,我们可以了解到,AbstractSessionFactoryBean继承了InitializingBean接口,并实现了其afterPropertiesSet方法,该方法是在Spring IoC容器初始化完成之后由IoC容器回调的方法,分析AbstractSessionFactoryBean的工作流程如下: (1).Spring管理Hibernate会话工厂的IoC容器AbstractSessionFactoryBean初始化完成,IoC容器回调afterPropertiesSet方法创建单态模式的Hivbernate会话工厂。 (2).应用通过getObject方法向Spring管理Hibernate会话工厂的IoC容器AbstractSessionFactoryBean索取Hibernate会话工厂。 下面我们继续分析AbstractSessionFactoryBean子类LocalSessionFactoryBean创建Hibernate会话工厂的过程。 3.LocalSessionFactoryBean创建SessionFactory: Spring中管理Hibernate会话工厂的IoC容器AbstractSessionFactoryBean通过委派模式调用其子类LocalSessionFactoryBean的buildSessionFactory创建Hibernate会话工厂,源码如下: [java] view plaincopyprint? //创建Hibernate会话工厂

protected SessionFactory buildSessionFactory() throws Exception {

//获取Hibernate配置

Configuration config = newConfiguration();

//获取数据源

DataSource dataSource = getDataSource();

//配置数据源,事务管理器,缓存等等,将这些配置设置当对应的线程局部变量中,

//使资源和当前线程绑定起来

if (dataSource != null) {

//配置数据源

configTimeDataSourceHolder.set(dataSource);

}

if (this.jtaTransactionManager != null) {

//配置jta事务管理器

configTimeTransactionManagerHolder.set(this.jtaTransactionManager);

}

if (this.cacheRegionFactory != null) {

//配置缓存区域工厂

configTimeRegionFactoryHolder.set(this.cacheRegionFactory);

}

if (this.cacheProvider != null) {

//配置缓存提供者

configTimeCacheProviderHolder.set(this.cacheProvider);

}

if (this.lobHandler != null) {

//配置lob处理器,用于处理clob/blob等大字段类型映射

configTimeLobHandlerHolder.set(this.lobHandler);

}

//Hibernate不允许显示设置类加载器,因此需要暴露相应的线程上下文类加载器

Thread currentThread = Thread.currentThread();

ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();

boolean overrideClassLoader =

(this.beanClassLoader != null && !this.beanClassLoader.equals(threadContextClassLoader));

//用当前类加载器覆盖当前线程上下文类加载器

if (overrideClassLoader) {

currentThread.setContextClassLoader(this.beanClassLoader);

}

//配置Hibernate相关属性

try {

//如果Hibernate会话工厂暴露一个会话包装的代理

if (isExposeTransactionAwareSessionFactory()) {

//使用Spring管理的Session作为Hibernate当前会话

config.setProperty(

Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());

}

//如果Hibernate会话工厂指定了事务管理器,则使用Hibernate的事务管理器

if (this.jtaTransactionManager != null) {

config.setProperty(

Environment.TRANSACTION_STRATEGY, JTATransactionFactory.class.getName());

config.setProperty(

Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.class.getName());

}

//如果Hibernate会话工厂没有指定事务管理器,则使用Spring管理的事务

else {

config.setProperty(

Environment.TRANSACTION_STRATEGY, SpringTransactionFactory.class.getName());

}

//设置SessionFactory级别的实体拦截器

if (this.entityInterceptor != null) {

config.setInterceptor(this.entityInterceptor);

}

//设置命名规则

if (this.namingStrategy != null) {

config.setNamingStrategy(this.namingStrategy);

}

//注册指定的Hibernate类型定义

if (this.typeDefinitions != null) {

//通过JDK反射机制,获取Hibernate配置文件中的createMappings方法

Method createMappings = Configuration.class.getMethod("createMappings");

//通过JDK反射,获取createMappings方法返回的org.hibernate.cfg.Mappings对//象的addTypeDef方法,该方法的三个参数类型为:String,String和Properties

Method addTypeDef = createMappings.getReturnType().getMethod(

"addTypeDef", String.class, String.class, Properties.class);

//通过JDK反射机制调用Hibernate配置中的createMappings方法,

//返回org.hibernate.cfg.Mappings对象

Object mappings = ReflectionUtils.invokeMethod(createMappings, config);

//遍历Hibernate中所有注册的类型定义

for (TypeDefinitionBean typeDef : this.typeDefinitions) {

//通过反射机制,调用org.hibernate.cfg.Mappings对象的

//addTypeDef方法,该方法的三个参数分别为:类型名称,类型实

//现类,类型参数,为Hibernate添加类型定义

ReflectionUtils.invokeMethod(addTypeDef, mappings,

typeDef.getTypeName(), typeDef.getTypeClass(), typeDef.getParameters());

}

}

//注册Hibernate过滤器

if (this.filterDefinitions != null) {

for (FilterDefinition filterDef : this.filterDefinitions) {

config.addFilterDefinition(filterDef);

}

}

//从给定资源路径加载Hibernate配置

if (this.configLocations != null) {

for (Resource resource : this.configLocations) {

config.configure(resource.getURL());

}

}

//添加Hibernate属性

if (this.hibernateProperties != null) {

config.addProperties(this.hibernateProperties);

}

//配置数据源

if (dataSource != null) {

//Spring中默认的Hibernate数据源连接提供类

Class providerClass = LocalDataSourceConnectionProvider.class;

//如果使用了事务包装数据源或者使用事务包装数据源代理,则使用

//TransactionAwareDataSourceConnectionProvider作为连接提供类

if (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy) {

providerClass = TransactionAwareDataSourceConnectionProvider.class;

}

//如果Hibernate配置文件中指定事务管理策略,则使用

//LocalJtaDataSourceConnectionProvider作为数据源连接提供类

else if (config.getProperty(Environment.TRANSACTION_MANAGER_STRATEGY) != null) {

providerClass = LocalJtaDataSourceConnectionProvider.class;

}

//设置Hibernate的数据源连接提供类

config.setProperty(Environment.CONNECTION_PROVIDER, providerClass.getName());

}

//如果Hibernate配置中指定了缓存区域工厂,则使用Spring提供的Hibernate

//缓存区域工厂

if (this.cacheRegionFactory != null) {

config.setProperty(Environment.CACHE_REGION_FACTORY,

"org.springframework.orm.hibernate3.LocalRegionFactoryProxy");

}

//如果Hibernate配置中指定了缓存提供类,则使用Spring提供的

//LocalCacheProviderProxy作为Hibernate缓存提供者

else if (this.cacheProvider != null) {

config.setProperty(Environment.CACHE_PROVIDER, LocalCacheProviderProxy.class.getName());

}

//如果Hibernate配置中指定了实体映射资源,则注册给定的Hibernate映射

if (this.mappingResources != null) {

//遍历给定的Hibernate映射资源

for (String mapping : this.mappingResources) {

//定位classpath中的Hibernate映射资源

Resource resource = new ClassPathResource(mapping.trim(), this.beanClassLoader);

//将Hibernate映射资源输入流添加到Hibernate配置输入流中

config.addInputStream(resource.getInputStream());

}

}

//如果Hibernate配置中指定了实体映射文件路径

if (this.mappingLocations != null) {

//遍历给定的路径,将Hibernate实体映射文件输入流添加到Hibernate

//配置输入流中

for (Resource resource : this.mappingLocations) {

config.addInputStream(resource.getInputStream());

}

}

//如果Hibernate配置中指定了缓存映射路径

if (this.cacheableMappingLocations != null) {

//将给定的缓存映射文件添加到Hibernate配置的缓存文件中

for (Resource resource : this.cacheableMappingLocations) {

config.addCacheableFile(resource.getFile());

}

}

//如果Hibernate配置中指定了包含在jar文件中的映射文件路径

if (this.mappingJarLocations != null) {

//将包含在jar文件中的映射文件添加到Hibernate配置中

for (Resource resource : this.mappingJarLocations) {

config.addJar(resource.getFile());

}

}

//如果Hibernate配置中指定了包含映射文件的目录路径

if (this.mappingDirectoryLocations != null) {

//将包含映射文件的给定目录添加到Hibernate配置中

for (Resource resource : this.mappingDirectoryLocations) {

File file = resource.getFile();

if (!file.isDirectory()) {

throw new IllegalArgumentException(

"Mapping directory location [" + resource + "] does not denote a directory");

}

config.addDirectory(file);

}

}

//编译Hibernate需要的映射信息

postProcessMappings(config);

config.buildMappings();

//如果Hibernate配置中指定了实体缓存策略

if (this.entityCacheStrategies != null) {

//为映射实体设置缓存策略

for (Enumeration classNames = this.entityCacheStrategies.propertyNames(); classNames.hasMoreElements();) {

String className = (String) classNames.nextElement();

//获取缓存策略属性值,将csv格式数据转换为字符串数组

String[] strategyAndRegion =

StringUtils.commaDelimitedListToStringArray(this.entityCacheStrategies.getProperty(className));

//如果缓存策略属性值多于2个,则只给Hibernate设置前两个值

if (strategyAndRegion.length > 1) {

//获取Hibernate配置中的setCacheConcurrencyStrategy方法

Method setCacheConcurrencyStrategy = Configuration.class.getMethod(

"setCacheConcurrencyStrategy", String.class, String.class, String.class);

//通过反射机制调用Hibernate配置对象的setCacheConcurrencyStrategy方法

ReflectionUtils.invokeMethod(setCacheConcurrencyStrategy, config,

className, strategyAndRegion[0], strategyAndRegion[1]);

}

//缓存策略属性值只有一个,则只需设置一个

else if (strategyAndRegion.length > 0) {

config.setCacheConcurrencyStrategy(className, strategyAndRegion[0]);

}

}

}

//如果Hibernate配置了集合缓存策略

if (this.collectionCacheStrategies != null) {

//为映射的集合注册缓存策略

for (Enumeration collRoles = this.collectionCacheStrategies.propertyNames(); collRoles.hasMoreElements();) {

String collRole = (String) collRoles.nextElement();

String[] strategyAndRegion =

StringUtils.commaDelimitedListToStringArray(this.collectionCacheStrategies.getProperty(collRole));

if (strategyAndRegion.length > 1) {

config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0], strategyAndRegion[1]);

}

else if (strategyAndRegion.length > 0) {

config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0]);

}

}

}

//注册Hibernate事件监听器

if (this.eventListeners != null) {

for (Map.Entry<String, Object> entry : this.eventListeners.entrySet()) {

//监听事件类型

String listenerType = entry.getKey();

//监听类对象

Object listenerObject = entry.getValue();

//如果监听类对象类型是集合

if (listenerObject instanceof Collection) {

Collection<Object> listeners = (Collection<Object>) listenerObject;

EventListeners listenerRegistry = config.getEventListeners();

//获取给定监听类型的所有监听类

Object[] listenerArray =

(Object[]) Array.newInstance(listenerRegistry.getListenerClassFor(listenerType), listeners.size());

listenerArray = listeners.toArray(listenerArray);

//Hibernate配置设置集合类型的监听类

config.setListeners(listenerType, listenerArray);

}

// Hibernate配置设置普通的监听类

else {

config.setListener(listenerType, listenerObject);

}

}

}

//Hibernate配置完成,客户自定义处理

postProcessConfiguration(config);

logger.info("Building new Hibernate SessionFactory");

this.configuration = config;

//根据Hibernate配置创建SessionFactory对象

return newSessionFactory(config);

}

//清空线程绑定的资源

finally {

if (dataSource != null) {

configTimeDataSourceHolder.remove();

}

if (this.jtaTransactionManager != null) {

configTimeTransactionManagerHolder.remove();

}

if (this.cacheRegionFactory != null) {

configTimeCacheProviderHolder.remove();

}

if (this.cacheProvider != null) {

configTimeCacheProviderHolder.remove();

}

if (this.lobHandler != null) {

configTimeLobHandlerHolder.remove();

}

if (overrideClassLoader) {

currentThread.setContextClassLoader(threadContextClassLoader);

}

}

}

//根据Hibernate配置创建SessionFactory

protected SessionFactory newSessionFactory(Configuration config) throws HibernateException {

return config.buildSessionFactory();

}

//创建Hibernate会话工厂protected SessionFactory buildSessionFactory() throws Exception { //获取Hibernate配置 Configuration config = newConfiguration(); //获取数据源 DataSource dataSource = getDataSource(); //配置数据源,事务管理器,缓存等等,将这些配置设置当对应的线程局部变量中, //使资源和当前线程绑定起来 if (dataSource != null) { //配置数据源 configTimeDataSourceHolder.set(dataSource); } if (this.jtaTransactionManager != null) { //配置jta事务管理器 configTimeTransactionManagerHolder.set(this.jtaTransactionManager); } if (this.cacheRegionFactory != null) { //配置缓存区域工厂 configTimeRegionFactoryHolder.set(this.cacheRegionFactory); } if (this.cacheProvider != null) { //配置缓存提供者 configTimeCacheProviderHolder.set(this.cacheProvider); } if (this.lobHandler != null) { //配置lob处理器,用于处理clob/blob等大字段类型映射 configTimeLobHandlerHolder.set(this.lobHandler); } //Hibernate不允许显示设置类加载器,因此需要暴露相应的线程上下文类加载器 Thread currentThread = Thread.currentThread(); ClassLoader threadContextClassLoader = currentThread.getContextClassLoader(); boolean overrideClassLoader = (this.beanClassLoader != null && !this.beanClassLoader.equals(threadContextClassLoader)); //用当前类加载器覆盖当前线程上下文类加载器 if (overrideClassLoader) { currentThread.setContextClassLoader(this.beanClassLoader); } //配置Hibernate相关属性 try { //如果Hibernate会话工厂暴露一个会话包装的代理 if (isExposeTransactionAwareSessionFactory()) { //使用Spring管理的Session作为Hibernate当前会话 config.setProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName()); } //如果Hibernate会话工厂指定了事务管理器,则使用Hibernate的事务管理器 if (this.jtaTransactionManager != null) { config.setProperty( Environment.TRANSACTION_STRATEGY, JTATransactionFactory.class.getName()); config.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.class.getName()); } //如果Hibernate会话工厂没有指定事务管理器,则使用Spring管理的事务 else { config.setProperty( Environment.TRANSACTION_STRATEGY, SpringTransactionFactory.class.getName()); } //设置SessionFactory级别的实体拦截器 if (this.entityInterceptor != null) { config.setInterceptor(this.entityInterceptor); } //设置命名规则 if (this.namingStrategy != null) { config.setNamingStrategy(this.namingStrategy); } //注册指定的Hibernate类型定义 if (this.typeDefinitions != null) { //通过JDK反射机制,获取Hibernate配置文件中的createMappings方法 Method createMappings = Configuration.class.getMethod("createMappings");//通过JDK反射,获取createMappings方法返回的org.hibernate.cfg.Mappings对//象的addTypeDef方法,该方法的三个参数类型为:String,String和Properties Method addTypeDef = createMappings.getReturnType().getMethod( "addTypeDef", String.class, String.class, Properties.class); //通过JDK反射机制调用Hibernate配置中的createMappings方法, //返回org.hibernate.cfg.Mappings对象 Object mappings = ReflectionUtils.invokeMethod(createMappings, config); //遍历Hibernate中所有注册的类型定义 for (TypeDefinitionBean typeDef : this.typeDefinitions) { //通过反射机制,调用org.hibernate.cfg.Mappings对象的 //addTypeDef方法,该方法的三个参数分别为:类型名称,类型实//现类,类型参数,为Hibernate添加类型定义 ReflectionUtils.invokeMethod(addTypeDef, mappings, typeDef.getTypeName(), typeDef.getTypeClass(), typeDef.getParameters()); } } //注册Hibernate过滤器 if (this.filterDefinitions != null) { for (FilterDefinition filterDef : this.filterDefinitions) { config.addFilterDefinition(filterDef); } } //从给定资源路径加载Hibernate配置 if (this.configLocations != null) { for (Resource resource : this.configLocations) { config.configure(resource.getURL()); } } //添加Hibernate属性 if (this.hibernateProperties != null) { config.addProperties(this.hibernateProperties); } //配置数据源 if (dataSource != null) { //Spring中默认的Hibernate数据源连接提供类 Class providerClass = LocalDataSourceConnectionProvider.class; //如果使用了事务包装数据源或者使用事务包装数据源代理,则使用 //TransactionAwareDataSourceConnectionProvider作为连接提供类 if (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy) { providerClass = TransactionAwareDataSourceConnectionProvider.class; } //如果Hibernate配置文件中指定事务管理策略,则使用 //LocalJtaDataSourceConnectionProvider作为数据源连接提供类 else if (config.getProperty(Environment.TRANSACTION_MANAGER_STRATEGY) != null) { providerClass = LocalJtaDataSourceConnectionProvider.class; } //设置Hibernate的数据源连接提供类 config.setProperty(Environment.CONNECTION_PROVIDER, providerClass.getName()); } //如果Hibernate配置中指定了缓存区域工厂,则使用Spring提供的Hibernate //缓存区域工厂 if (this.cacheRegionFactory != null) { config.setProperty(Environment.CACHE_REGION_FACTORY, "org.springframework.orm.hibernate3.LocalRegionFactoryProxy"); } //如果Hibernate配置中指定了缓存提供类,则使用Spring提供的 //LocalCacheProviderProxy作为Hibernate缓存提供者 else if (this.cacheProvider != null) { config.setProperty(Environment.CACHE_PROVIDER, LocalCacheProviderProxy.class.getName()); } //如果Hibernate配置中指定了实体映射资源,则注册给定的Hibernate映射 if (this.mappingResources != null) { //遍历给定的Hibernate映射资源 for (String mapping : this.mappingResources) { //定位classpath中的Hibernate映射资源 Resource resource = new ClassPathResource(mapping.trim(), this.beanClassLoader); //将Hibernate映射资源输入流添加到Hibernate配置输入流中 config.addInputStream(resource.getInputStream()); } } //如果Hibernate配置中指定了实体映射文件路径 if (this.mappingLocations != null) { //遍历给定的路径,将Hibernate实体映射文件输入流添加到Hibernate //配置输入流中 for (Resource resource : this.mappingLocations) { config.addInputStream(resource.getInputStream()); } } //如果Hibernate配置中指定了缓存映射路径 if (this.cacheableMappingLocations != null) { //将给定的缓存映射文件添加到Hibernate配置的缓存文件中 for (Resource resource : this.cacheableMappingLocations) { config.addCacheableFile(resource.getFile()); } } //如果Hibernate配置中指定了包含在jar文件中的映射文件路径 if (this.mappingJarLocations != null) { //将包含在jar文件中的映射文件添加到Hibernate配置中 for (Resource resource : this.mappingJarLocations) { config.addJar(resource.getFile()); } } //如果Hibernate配置中指定了包含映射文件的目录路径 if (this.mappingDirectoryLocations != null) { //将包含映射文件的给定目录添加到Hibernate配置中 for (Resource resource : this.mappingDirectoryLocations) { File file = resource.getFile(); if (!file.isDirectory()) { throw new IllegalArgumentException( "Mapping directory location [" + resource + "] does not denote a directory"); } config.addDirectory(file); } } //编译Hibernate需要的映射信息 postProcessMappings(config); config.buildMappings(); //如果Hibernate配置中指定了实体缓存策略 if (this.entityCacheStrategies != null) { //为映射实体设置缓存策略 for (Enumeration classNames = this.entityCacheStrategies.propertyNames(); classNames.hasMoreElements();) { String className = (String) classNames.nextElement(); //获取缓存策略属性值,将csv格式数据转换为字符串数组 String[] strategyAndRegion = StringUtils.commaDelimitedListToStringArray(this.entityCacheStrategies.getProperty(className)); //如果缓存策略属性值多于2个,则只给Hibernate设置前两个值 if (strategyAndRegion.length > 1) {//获取Hibernate配置中的setCacheConcurrencyStrategy方法 Method setCacheConcurrencyStrategy = Configuration.class.getMethod( "setCacheConcurrencyStrategy", String.class, String.class, String.class); //通过反射机制调用Hibernate配置对象的setCacheConcurrencyStrategy方法 ReflectionUtils.invokeMethod(setCacheConcurrencyStrategy, config, className, strategyAndRegion[0], strategyAndRegion[1]); } //缓存策略属性值只有一个,则只需设置一个 else if (strategyAndRegion.length > 0) { config.setCacheConcurrencyStrategy(className, strategyAndRegion[0]); } } } //如果Hibernate配置了集合缓存策略 if (this.collectionCacheStrategies != null) { //为映射的集合注册缓存策略 for (Enumeration collRoles = this.collectionCacheStrategies.propertyNames(); collRoles.hasMoreElements();) { String collRole = (String) collRoles.nextElement(); String[] strategyAndRegion = StringUtils.commaDelimitedListToStringArray(this.collectionCacheStrategies.getProperty(collRole)); if (strategyAndRegion.length > 1) { config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0], strategyAndRegion[1]); } else if (strategyAndRegion.length > 0) { config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0]); } } } //注册Hibernate事件监听器 if (this.eventListeners != null) { for (Map.Entry<String, Object> entry : this.eventListeners.entrySet()) { //监听事件类型 String listenerType = entry.getKey(); //监听类对象 Object listenerObject = entry.getValue(); //如果监听类对象类型是集合 if (listenerObject instanceof Collection) { Collection<Object> listeners = (Collection<Object>) listenerObject; EventListeners listenerRegistry = config.getEventListeners(); //获取给定监听类型的所有监听类 Object[] listenerArray = (Object[]) Array.newInstance(listenerRegistry.getListenerClassFor(listenerType), listeners.size()); listenerArray = listeners.toArray(listenerArray); //Hibernate配置设置集合类型的监听类 config.setListeners(listenerType, listenerArray); } // Hibernate配置设置普通的监听类 else { config.setListener(listenerType, listenerObject); } } } //Hibernate配置完成,客户自定义处理 postProcessConfiguration(config); logger.info("Building new Hibernate SessionFactory"); this.configuration = config; //根据Hibernate配置创建SessionFactory对象 return newSessionFactory(config); } //清空线程绑定的资源 finally { if (dataSource != null) { configTimeDataSourceHolder.remove(); } if (this.jtaTransactionManager != null) { configTimeTransactionManagerHolder.remove(); } if (this.cacheRegionFactory != null) { configTimeCacheProviderHolder.remove(); } if (this.cacheProvider != null) { configTimeCacheProviderHolder.remove(); } if (this.lobHandler != null) { configTimeLobHandlerHolder.remove(); } if (overrideClassLoader) { currentThread.setContextClassLoader(threadContextClassLoader); } } }//根据Hibernate配置创建SessionFactoryprotected SessionFactory newSessionFactory(Configuration config) throws HibernateException { return config.buildSessionFactory(); } 上述代码非常的长,但是所做的工作非常的清楚,即获取Hibernate的配置,然后设置Hibernate配置,最后生成SessionFactory的过程。 4.HibernateTemplate实现: 和Spring对jdbc封装类似,Spring使用HibernateTemplate对Hibernate也进行了一下API封装,通过execute回调来调用Hibernate的相关操作处理,接下来简单分析HibernateTemplate的核心实现。 (1). execute相关方法的实现: 与JdbcTemplate类似,execute相关方法也是HibernateTemplate的基础核心方法,在execute相关方法中,Spring提供获取Hibernate Session,为当前的Session进行事务处理等通用的操作,源码如下: [java] view plaincopyprint? //最基础的execute方法

public <T> T execute(HibernateCallback<T> action) throws DataAccessException {

return doExecute(action, false, false);

}

//需要在新的Hibernate Session中执行的execute方法

public <T> T executeWithNewSession(HibernateCallback<T> action) {

return doExecute(action, true, false);

}

//需要在Hibernate本地Session中执行的execute方法

public <T> T executeWithNativeSession(HibernateCallback<T> action) {

return doExecute(action, false, true);

}

//真正调用Hibernate API的地方

protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession)

throws DataAccessException {

Assert.notNull(action, "Callback object must not be null");

//获取Hibernate会话,判断是否需要新的Session

Session session = (enforceNewSession ?

SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession());

//是否存在事务

boolean existingTransaction = (!enforceNewSession &&

(!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory())));

if (existingTransaction) {

logger.debug("Found thread-bound Session for HibernateTemplate");

}

//刷新模式

FlushMode previousFlushMode = null;

try {

//根据Hibernate Session和事务类型应用相应的刷新模式

previousFlushMode = applyFlushMode(session, existingTransaction);

//对Session开启过滤器

enableFilters(session);

//判断Hibernate Session是否需要代理包装

Session sessionToExpose =

(enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session));

//对HibernateCallBack中回调函数的调用,真正调用Hibernate API

T result = action.doInHibernate(sessionToExpose);

flushIfNecessary(session, existingTransaction);

return result;

}

catch (HibernateException ex) {

throw convertHibernateAccessException(ex);

}

catch (SQLException ex) {

throw convertJdbcAccessException(ex);

}

catch (RuntimeException ex) {

throw ex;

}

finally {

//如果存在事务,则调用完毕之后不关闭Session

if (existingTransaction) {

logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");

//对Session禁用过滤器

disableFilters(session);

if (previousFlushMode != null) {

session.setFlushMode(previousFlushMode);

}

}

//如果不存在事务,则关闭当前的Session

else {

if (isAlwaysUseNewSession()) {

SessionFactoryUtils.closeSession(session);

}

else {

SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());

}

}

}

}

//最基础的execute方法public <T> T execute(HibernateCallback<T> action) throws DataAccessException { return doExecute(action, false, false); } //需要在新的Hibernate Session中执行的execute方法public <T> T executeWithNewSession(HibernateCallback<T> action) { return doExecute(action, true, false); } //需要在Hibernate本地Session中执行的execute方法public <T> T executeWithNativeSession(HibernateCallback<T> action) { return doExecute(action, false, true); } //真正调用Hibernate API的地方protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); //获取Hibernate会话,判断是否需要新的Session Session session = (enforceNewSession ? SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession()); //是否存在事务 boolean existingTransaction = (!enforceNewSession && (!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory()))); if (existingTransaction) { logger.debug("Found thread-bound Session for HibernateTemplate"); } //刷新模式 FlushMode previousFlushMode = null; try { //根据Hibernate Session和事务类型应用相应的刷新模式 previousFlushMode = applyFlushMode(session, existingTransaction); //对Session开启过滤器 enableFilters(session); //判断Hibernate Session是否需要代理包装 Session sessionToExpose = (enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session)); //对HibernateCallBack中回调函数的调用,真正调用Hibernate API T result = action.doInHibernate(sessionToExpose); flushIfNecessary(session, existingTransaction); return result; } catch (HibernateException ex) { throw convertHibernateAccessException(ex); } catch (SQLException ex) { throw convertJdbcAccessException(ex); } catch (RuntimeException ex) { throw ex; } finally { //如果存在事务,则调用完毕之后不关闭Session if (existingTransaction) { logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate"); //对Session禁用过滤器 disableFilters(session); if (previousFlushMode != null) { session.setFlushMode(previousFlushMode); } } //如果不存在事务,则关闭当前的Session else { if (isAlwaysUseNewSession()) { SessionFactoryUtils.closeSession(session); } else { SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory()); } } } } (2).HibernateTemplate中增删改查操作的简单实现: 以查询为例,分析HibernateTemplate如何通过execute方法回调Hibernate相应的API,源码如下: [java] view plaincopyprint? //查询指定Id的实体

public Object get(String entityName, Serializable id) throws DataAccessException {

return get(entityName, id, null);

}

//真正调用Hibernate API查询的方法

public Object get(final String entityName, final Serializable id, final LockMode lockMode)

throws DataAccessException {

//调用Hibernate本地查询方法,参数是一个实现HibernateCallback接口的

//匿名内部类,用于execute方法回调

return executeWithNativeSession(new HibernateCallback<Object>() {

//execute方法回调,真正调用Hibernate查询的方法

public Object doInHibernate(Session session) throws HibernateException {

if (lockMode != null) {

return session.get(entityName, id, lockMode);

}

else {

return session.get(entityName, id);

}

}

});

}

//查询指定Id的实体public Object get(String entityName, Serializable id) throws DataAccessException { return get(entityName, id, null); }//真正调用Hibernate API查询的方法public Object get(final String entityName, final Serializable id, final LockMode lockMode) throws DataAccessException { //调用Hibernate本地查询方法,参数是一个实现HibernateCallback接口的 //匿名内部类,用于execute方法回调 return executeWithNativeSession(new HibernateCallback<Object>() { //execute方法回调,真正调用Hibernate查询的方法 public Object doInHibernate(Session session) throws HibernateException { if (lockMode != null) { return session.get(entityName, id, lockMode); } else { return session.get(entityName, id); } } }); } 其他的load,update等等调用Hibernate的方法类似,各自提供不同的HibernateCallback回调来真正调用Hibernate相应方法。 5.Hibernate管理Session: 在4分析HibernateTemplate的doExecute法源码时我们看到,Spring根据是否需要新Session的判断,使用getSession和getNewSession两种不同的获取Session的方法,Spring中通过SessionFactoryUtils来管理HibernateSession,分析SessionFactoryUtils管理Session的实现源码: (1).getNewSession实现: [java] view plaincopyprint? //获取新Session

public static Session getNewSession(SessionFactory sessionFactory, Interceptor entityInterceptor) {

Assert.notNull(sessionFactory, "No SessionFactory specified");

try {

//获取事务管理器中的sessionFactory线程局部变量

SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);

//如果当前线程绑定了SessionFactory资源

if (sessionHolder != null && !sessionHolder.isEmpty()) {

//如果有实体拦截器,则打开一个有实体拦截器的Session连接

if (entityInterceptor != null) {

return sessionFactory.openSession(sessionHolder.getAnySession().connection(), entityInterceptor);

}

//如果没有实体拦截器,则直接打开当前线程中绑定的Session连接

else {

return sessionFactory.openSession(sessionHolder.getAnySession().connection());

}

}

//如果当前线程没有绑定SessionFactory资源

else {

//如果有实体拦截器

if (entityInterceptor != null) {

//打开一个包含给定实体拦截器的Session

return sessionFactory.openSession(entityInterceptor);

}

//如果没有实体拦截器,则直接打开一个新的Session

else {

return sessionFactory.openSession();

}

}

}

catch (HibernateException ex) {

throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);

}

}

//获取新Sessionpublic static Session getNewSession(SessionFactory sessionFactory, Interceptor entityInterceptor) { Assert.notNull(sessionFactory, "No SessionFactory specified"); try { //获取事务管理器中的sessionFactory线程局部变量 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); //如果当前线程绑定了SessionFactory资源 if (sessionHolder != null && !sessionHolder.isEmpty()) { //如果有实体拦截器,则打开一个有实体拦截器的Session连接 if (entityInterceptor != null) { return sessionFactory.openSession(sessionHolder.getAnySession().connection(), entityInterceptor); } //如果没有实体拦截器,则直接打开当前线程中绑定的Session连接 else { return sessionFactory.openSession(sessionHolder.getAnySession().connection()); } } //如果当前线程没有绑定SessionFactory资源 else { //如果有实体拦截器 if (entityInterceptor != null) { //打开一个包含给定实体拦截器的Session return sessionFactory.openSession(entityInterceptor); } //如果没有实体拦截器,则直接打开一个新的Session else { return sessionFactory.openSession(); } } } catch (HibernateException ex) { throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); } } (2).getSession实现: [java] view plaincopyprint? //获取Hibernate Session的入口方法

public static Session getSession(SessionFactory sessionFactory, boolean allowCreate)

throws DataAccessResourceFailureException, IllegalStateException {

try {

//通过调用doGetSession来获取Hibernate Session

return doGetSession(sessionFactory, null, null, allowCreate);

}

catch (HibernateException ex) {

throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);

}

}

//获取Hibernate Session

private static Session doGetSession(

SessionFactory sessionFactory, Interceptor entityInterceptor,

SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)

throws HibernateException, IllegalStateException {

Assert.notNull(sessionFactory, "No SessionFactory specified");

//获取和当前线程绑定的Session资源

SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);

//如果当前线程有绑定了Session的资源,即已经有创建了的Session

if (sessionHolder != null && !sessionHolder.isEmpty()) {

Session session = null;

//如果Spring事务管理是activate的

if (TransactionSynchronizationManager.isSynchronizationActive() &&

sessionHolder.doesNotHoldNonDefaultSession()) {

//获取当前线程绑定的有效Session

session = sessionHolder.getValidatedSession();

//如果获取了当前线程绑定的有效Session,并且当前线程绑定的Session

//资源是事务同步的

if (session != null && !sessionHolder.isSynchronizedWithTransaction()) {

logger.debug("Registering Spring transaction synchronization for existing Hibernate Session");

//为已有的Hibernate Session注册Spring事务同步

TransactionSynchronizationManager.registerSynchronization(

new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false));

sessionHolder.setSynchronizedWithTransaction(true);

//根据实现级别设置Session刷新模式

FlushMode flushMode = session.getFlushMode();

if (flushMode.lessThan(FlushMode.COMMIT) &&

!TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {

session.setFlushMode(FlushMode.AUTO);

sessionHolder.setPreviousFlushMode(flushMode);

}

}

}

//如果没有Spring管理的事务

else {

//使用jta事务同步

session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator);

}

if (session != null) {

return session;

}

}

logger.debug("Opening Hibernate Session");

//当前线程没有绑定Session资源,则需要创建新Session

Session session = (entityInterceptor != null ?

sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession());

//如果Spring管理的事务是activate的

if (TransactionSynchronizationManager.isSynchronizationActive()) {

logger.debug("Registering Spring transaction synchronization for new Hibernate Session");

SessionHolder holderToUse = sessionHolder;

//将新创建的Session添加到当前线程局部变量中

if (holderToUse == null) {

holderToUse = new SessionHolder(session);

}

else {

holderToUse.addSession(session);

}

//设置Session刷新模式

if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {

session.setFlushMode(FlushMode.MANUAL);

}

//为新创建的Hibernate Session注册Spring事务

TransactionSynchronizationManager.registerSynchronization(

new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true));

holderToUse.setSynchronizedWithTransaction(true);

//将新创建的Session与当前线资源程绑定

if (holderToUse != sessionHolder) {

TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse);

}

}

//如果没有Spring事务

else {

//为Session设置JTA事务

registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder);

}

//判断是否允许返回给定的Session

if (!allowCreate && !isSessionTransactional(session, sessionFactory)) {

closeSession(session);

throw new IllegalStateException("No Hibernate Session bound to thread, " +

"and configuration does not allow creation of non-transactional one here");

}

return session;

}

//获取Hibernate Session的入口方法public static Session getSession(SessionFactory sessionFactory, boolean allowCreate) throws DataAccessResourceFailureException, IllegalStateException { try { //通过调用doGetSession来获取Hibernate Session return doGetSession(sessionFactory, null, null, allowCreate); } catch (HibernateException ex) { throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); } } //获取Hibernate Sessionprivate static Session doGetSession( SessionFactory sessionFactory, Interceptor entityInterceptor, SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate) throws HibernateException, IllegalStateException { Assert.notNull(sessionFactory, "No SessionFactory specified"); //获取和当前线程绑定的Session资源 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); //如果当前线程有绑定了Session的资源,即已经有创建了的Session if (sessionHolder != null && !sessionHolder.isEmpty()) { Session session = null; //如果Spring事务管理是activate的 if (TransactionSynchronizationManager.isSynchronizationActive() && sessionHolder.doesNotHoldNonDefaultSession()) { //获取当前线程绑定的有效Session session = sessionHolder.getValidatedSession(); //如果获取了当前线程绑定的有效Session,并且当前线程绑定的Session //资源是事务同步的 if (session != null && !sessionHolder.isSynchronizedWithTransaction()) { logger.debug("Registering Spring transaction synchronization for existing Hibernate Session");//为已有的Hibernate Session注册Spring事务同步 TransactionSynchronizationManager.registerSynchronization( new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false)); sessionHolder.setSynchronizedWithTransaction(true); //根据实现级别设置Session刷新模式 FlushMode flushMode = session.getFlushMode(); if (flushMode.lessThan(FlushMode.COMMIT) && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { session.setFlushMode(FlushMode.AUTO); sessionHolder.setPreviousFlushMode(flushMode); } } } //如果没有Spring管理的事务 else { //使用jta事务同步 session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator); } if (session != null) { return session; } } logger.debug("Opening Hibernate Session"); //当前线程没有绑定Session资源,则需要创建新Session Session session = (entityInterceptor != null ? sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession()); //如果Spring管理的事务是activate的 if (TransactionSynchronizationManager.isSynchronizationActive()) { logger.debug("Registering Spring transaction synchronization for new Hibernate Session"); SessionHolder holderToUse = sessionHolder; //将新创建的Session添加到当前线程局部变量中 if (holderToUse == null) { holderToUse = new SessionHolder(session); } else { holderToUse.addSession(session); } //设置Session刷新模式 if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { session.setFlushMode(FlushMode.MANUAL); } //为新创建的Hibernate Session注册Spring事务 TransactionSynchronizationManager.registerSynchronization( new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true)); holderToUse.setSynchronizedWithTransaction(true); //将新创建的Session与当前线资源程绑定 if (holderToUse != sessionHolder) { TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse); } } //如果没有Spring事务 else { //为Session设置JTA事务 registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder); } //判断是否允许返回给定的Session if (!allowCreate && !isSessionTransactional(session, sessionFactory)) { closeSession(session); throw new IllegalStateException("No Hibernate Session bound to thread, " + "and configuration does not allow creation of non-transactional one here"); } return session; } 通过上面Spring对Hibernate Session管理的源码分析,我们了解到Spring已经将Hibernate Session的获取与关闭,Session的事务处理,以及Session与线程资源绑定等操作做了封装统一管理,为应用使用Hibernate提供了方便。

推荐:Spring框架学习【SqlMapClientTemplate对Ibatis的封装】

1. SqlMapClientFactoryBean: Spring中通过SqlMapClientTemplate提供对Ibatis的支持,与Spring对Hibernate的支持类似,Spring中SqlMapClientFactoryBean就是管

, 1.Spring中,不提供具体的ORM实现,而只是为应用提供对ORM产品的集成环境和使用平台,Spring将Hibernate的会话工厂通过IoC容器管理起来,并且将数据源注入,同时Spring为Hibernate提供了更上层的API封装,方便应用调用,本文通过分析相应源码了解Spring对Hibernate支持的实现。 2.AbstractSessionFactoryBean管理Hibernate会话工厂: 使用过Hibernate的人都知道,Hibernate的SessionFactory(会话工厂)是Hibernate的基础,SessionFactory管理Hibernate的相关配置和映射资源,Spring中通过AbstractSessionFactoryBean抽象类来管理Hibernate的会话工厂,AbstractSessionFactoryBean实现Spring的工厂Bean(FactoryBean)接口,因此AbstractSessionFactoryBean是一个Spring的工厂Bean,即Spring管理Hibernate的IoC容器,AbstractSessionFactoryBean的源码如下: [java] view plaincopyprint? public abstract class AbstractSessionFactoryBean

implements FactoryBean<SessionFactory>, InitializingBean, DisposableBean, PersistenceExceptionTranslator {

protected final Log logger = LogFactory.getLog(getClass());

//数据源

private DataSource dataSource;

//Hibernate会话使用Spring事务管理器包装的数据源

private boolean useTransactionAwareDataSource = false;

//从Hibernate会话工厂中获取的当前会话是否暴露给Spring事务来包装

private boolean exposeTransactionAwareSessionFactory = true;

//Hibernate SQL相关异常转换器

private SQLExceptionTranslator jdbcExceptionTranslator;

//Hibernate会话工厂

private SessionFactory sessionFactory;

//为会话工厂设置数据源,如果设置,则覆盖Hibernate配置文件中的数据源设置

public void setDataSource(DataSource dataSource) {

this.dataSource = dataSource;

}

public DataSource getDataSource() {

return this.dataSource;

}

//设置Hibernate会话工厂是否使用Spring事务(jdbc事务)包装的数据源,

//true,则使用Spring的jdbc事务;false,则使用Hibernate事务或者JTA

public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) {

this.useTransactionAwareDataSource = useTransactionAwareDataSource;

}

protected boolean isUseTransactionAwareDataSource() {

return this.useTransactionAwareDataSource;

}

//为通过Hibernate会话工厂getCurrentSession()方法获得的当前会话设置

//是否使用Spring会话包装

public void setExposeTransactionAwareSessionFactory(boolean exposeTransactionAwareSessionFactory) {

this.exposeTransactionAwareSessionFactory = exposeTransactionAwareSessionFactory;

}

protected boolean isExposeTransactionAwareSessionFactory() {

return this.exposeTransactionAwareSessionFactory;

}

//为Hibernate会话工厂设置JDBC异常转换器,当Hibernate产生的任何由jdbc异常

//引起的SQL异常时,使用jdbc异常覆盖Hibernate默认的SQL方言(Dialect)异常

public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) {

this.jdbcExceptionTranslator = jdbcExceptionTranslator;

}

//创建Hibernate会话工厂,IoC容器初始化回调方法

public void afterPropertiesSet() throws Exception {

//委托模式,调用AbstractSessionFactoryBean子类//LocalSessionFactoryBean实现的方法

SessionFactory rawSf = buildSessionFactory();

//如果需要,将给定的会话工厂使用代理包装

this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf);

//钩子方法,Hibernate会话工厂创建成功后,应用自定义处理

afterSessionFactoryCreation();

}

//如果有需要,将给定的Hibernate会话工厂用代理封装

protected SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) {

return rawSf;

}

//应用从Spring管理Hibernate会话工厂的IoC容器中获取SessionFactory

protected final SessionFactory getSessionFactory() {

if (this.sessionFactory == null) {

throw new IllegalStateException("SessionFactory not initialized yet");

}

return this.sessionFactory;

}

//当Spring管理Hibernate会话工厂的IoC容器关闭时关闭所创建的会话工厂

public void destroy() throws HibernateException {

logger.info("Closing Hibernate SessionFactory");

try {

beforeSessionFactoryDestruction();

}

finally {

this.sessionFactory.close();

}

}

//获取单态模式的Hibernate会话工厂

public SessionFactory getObject() {

return this.sessionFactory;

}

//获取Hibernate会话工厂的对象类型

public Class<? extends SessionFactory> getObjectType() {

return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class);

}

public boolean isSingleton() {

return true;

}

//转换异常

public DataAccessException translateExceptionIfPossible(RuntimeException ex) {

//如果异常时Hibernate异常类型

if (ex instanceof HibernateException) {

//转换Hibernate异常

return convertHibernateAccessException((HibernateException) ex);

}

//如果不是Hibernate异常,则返回null

return null;

}

//转换Hibernate异常

protected DataAccessException convertHibernateAccessException(HibernateException ex) {

//如果Hibernate会话工厂设置了Jdbc异常转换器,且给定的异常是jdbc异常类型,

//则使用设置的jdbc异常转换器转换给定的Hibernate异常

if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) {

JDBCException jdbcEx = (JDBCException) ex;

return this.jdbcExceptionTranslator.translate(

"Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException());

}

//如果Hibernate会话工厂没有设置jdbc异常转换器,或者给定异常不是jdbc异常

//类型,则使用Hibernate默认的异常转换器转换

return SessionFactoryUtils.convertHibernateAccessException(ex);

}

//创建Hibernate会话工厂

protected abstract SessionFactory buildSessionFactory() throws Exception;

//钩子方法,Hibernate会话工厂成功创建后操作处理

protected void afterSessionFactoryCreation() throws Exception {

}

//钩子方法,Hibernate会话工厂关闭前操作处理

protected void beforeSessionFactoryDestruction() {

}

}

public abstract class AbstractSessionFactoryBean implements FactoryBean<SessionFactory>, InitializingBean, DisposableBean, PersistenceExceptionTranslator { protected final Log logger = LogFactory.getLog(getClass()); //数据源 private DataSource dataSource;//Hibernate会话使用Spring事务管理器包装的数据源 private boolean useTransactionAwareDataSource = false; //从Hibernate会话工厂中获取的当前会话是否暴露给Spring事务来包装 private boolean exposeTransactionAwareSessionFactory = true; //Hibernate SQL相关异常转换器 private SQLExceptionTranslator jdbcExceptionTranslator; //Hibernate会话工厂 private SessionFactory sessionFactory; //为会话工厂设置数据源,如果设置,则覆盖Hibernate配置文件中的数据源设置 public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public DataSource getDataSource() { return this.dataSource; }//设置Hibernate会话工厂是否使用Spring事务(jdbc事务)包装的数据源,//true,则使用Spring的jdbc事务;false,则使用Hibernate事务或者JTA public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) { this.useTransactionAwareDataSource = useTransactionAwareDataSource; } protected boolean isUseTransactionAwareDataSource() { return this.useTransactionAwareDataSource; } //为通过Hibernate会话工厂getCurrentSession()方法获得的当前会话设置//是否使用Spring会话包装 public void setExposeTransactionAwareSessionFactory(boolean exposeTransactionAwareSessionFactory) { this.exposeTransactionAwareSessionFactory = exposeTransactionAwareSessionFactory; } protected boolean isExposeTransactionAwareSessionFactory() { return this.exposeTransactionAwareSessionFactory; } //为Hibernate会话工厂设置JDBC异常转换器,当Hibernate产生的任何由jdbc异常//引起的SQL异常时,使用jdbc异常覆盖Hibernate默认的SQL方言(Dialect)异常 public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { this.jdbcExceptionTranslator = jdbcExceptionTranslator; }//创建Hibernate会话工厂,IoC容器初始化回调方法 public void afterPropertiesSet() throws Exception {//委托模式,调用AbstractSessionFactoryBean子类//LocalSessionFactoryBean实现的方法 SessionFactory rawSf = buildSessionFactory(); //如果需要,将给定的会话工厂使用代理包装 this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf); //钩子方法,Hibernate会话工厂创建成功后,应用自定义处理 afterSessionFactoryCreation(); } //如果有需要,将给定的Hibernate会话工厂用代理封装 protected SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) { return rawSf; } //应用从Spring管理Hibernate会话工厂的IoC容器中获取SessionFactory protected final SessionFactory getSessionFactory() { if (this.sessionFactory == null) { throw new IllegalStateException("SessionFactory not initialized yet"); } return this.sessionFactory; } //当Spring管理Hibernate会话工厂的IoC容器关闭时关闭所创建的会话工厂 public void destroy() throws HibernateException { logger.info("Closing Hibernate SessionFactory"); try { beforeSessionFactoryDestruction(); } finally { this.sessionFactory.close(); } }//获取单态模式的Hibernate会话工厂 public SessionFactory getObject() { return this.sessionFactory; } //获取Hibernate会话工厂的对象类型 public Class<? extends SessionFactory> getObjectType() { return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class); } public boolean isSingleton() { return true; }//转换异常 public DataAccessException translateExceptionIfPossible(RuntimeException ex) { //如果异常时Hibernate异常类型 if (ex instanceof HibernateException) { //转换Hibernate异常 return convertHibernateAccessException((HibernateException) ex); } //如果不是Hibernate异常,则返回null return null; }//转换Hibernate异常 protected DataAccessException convertHibernateAccessException(HibernateException ex) { //如果Hibernate会话工厂设置了Jdbc异常转换器,且给定的异常是jdbc异常类型, //则使用设置的jdbc异常转换器转换给定的Hibernate异常 if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) { JDBCException jdbcEx = (JDBCException) ex; return this.jdbcExceptionTranslator.translate( "Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException()); }//如果Hibernate会话工厂没有设置jdbc异常转换器,或者给定异常不是jdbc异常//类型,则使用Hibernate默认的异常转换器转换 return SessionFactoryUtils.convertHibernateAccessException(ex); }//创建Hibernate会话工厂 protected abstract SessionFactory buildSessionFactory() throws Exception; //钩子方法,Hibernate会话工厂成功创建后操作处理 protected void afterSessionFactoryCreation() throws Exception { } //钩子方法,Hibernate会话工厂关闭前操作处理 protected void beforeSessionFactoryDestruction() { }} 通过分析Spring对Hibernate会话工厂管理的IoC容器AbstractSessionFactoryBean的源码,我们可以了解到,AbstractSessionFactoryBean继承了InitializingBean接口,并实现了其afterPropertiesSet方法,该方法是在Spring IoC容器初始化完成之后由IoC容器回调的方法,分析AbstractSessionFactoryBean的工作流程如下: (1).Spring管理Hibernate会话工厂的IoC容器AbstractSessionFactoryBean初始化完成,IoC容器回调afterPropertiesSet方法创建单态模式的Hivbernate会话工厂。 (2).应用通过getObject方法向Spring管理Hibernate会话工厂的IoC容器AbstractSessionFactoryBean索取Hibernate会话工厂。 下面我们继续分析AbstractSessionFactoryBean子类LocalSessionFactoryBean创建Hibernate会话工厂的过程。 3.LocalSessionFactoryBean创建SessionFactory: Spring中管理Hibernate会话工厂的IoC容器AbstractSessionFactoryBean通过委派模式调用其子类LocalSessionFactoryBean的buildSessionFactory创建Hibernate会话工厂,源码如下: [java] view plaincopyprint? //创建Hibernate会话工厂

protected SessionFactory buildSessionFactory() throws Exception {

//获取Hibernate配置

Configuration config = newConfiguration();

//获取数据源

DataSource dataSource = getDataSource();

//配置数据源,事务管理器,缓存等等,将这些配置设置当对应的线程局部变量中,

//使资源和当前线程绑定起来

if (dataSource != null) {

//配置数据源

configTimeDataSourceHolder.set(dataSource);

}

if (this.jtaTransactionManager != null) {

//配置jta事务管理器

configTimeTransactionManagerHolder.set(this.jtaTransactionManager);

}

if (this.cacheRegionFactory != null) {

//配置缓存区域工厂

configTimeRegionFactoryHolder.set(this.cacheRegionFactory);

}

if (this.cacheProvider != null) {

//配置缓存提供者

configTimeCacheProviderHolder.set(this.cacheProvider);

}

if (this.lobHandler != null) {

//配置lob处理器,用于处理clob/blob等大字段类型映射

configTimeLobHandlerHolder.set(this.lobHandler);

}

//Hibernate不允许显示设置类加载器,因此需要暴露相应的线程上下文类加载器

Thread currentThread = Thread.currentThread();

ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();

boolean overrideClassLoader =

(this.beanClassLoader != null && !this.beanClassLoader.equals(threadContextClassLoader));

//用当前类加载器覆盖当前线程上下文类加载器

if (overrideClassLoader) {

currentThread.setContextClassLoader(this.beanClassLoader);

}

//配置Hibernate相关属性

try {

//如果Hibernate会话工厂暴露一个会话包装的代理

if (isExposeTransactionAwareSessionFactory()) {

//使用Spring管理的Session作为Hibernate当前会话

config.setProperty(

Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());

}

//如果Hibernate会话工厂指定了事务管理器,则使用Hibernate的事务管理器

if (this.jtaTransactionManager != null) {

config.setProperty(

Environment.TRANSACTION_STRATEGY, JTATransactionFactory.class.getName());

config.setProperty(

Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.class.getName());

}

//如果Hibernate会话工厂没有指定事务管理器,则使用Spring管理的事务

else {

config.setProperty(

Environment.TRANSACTION_STRATEGY, SpringTransactionFactory.class.getName());

}

//设置SessionFactory级别的实体拦截器

if (this.entityInterceptor != null) {

config.setInterceptor(this.entityInterceptor);

}

//设置命名规则

if (this.namingStrategy != null) {

config.setNamingStrategy(this.namingStrategy);

}

//注册指定的Hibernate类型定义

if (this.typeDefinitions != null) {

//通过JDK反射机制,获取Hibernate配置文件中的createMappings方法

Method createMappings = Configuration.class.getMethod("createMappings");

//通过JDK反射,获取createMappings方法返回的org.hibernate.cfg.Mappings对//象的addTypeDef方法,该方法的三个参数类型为:String,String和Properties

Method addTypeDef = createMappings.getReturnType().getMethod(

"addTypeDef", String.class, String.class, Properties.class);

//通过JDK反射机制调用Hibernate配置中的createMappings方法,

//返回org.hibernate.cfg.Mappings对象

Object mappings = ReflectionUtils.invokeMethod(createMappings, config);

//遍历Hibernate中所有注册的类型定义

for (TypeDefinitionBean typeDef : this.typeDefinitions) {

//通过反射机制,调用org.hibernate.cfg.Mappings对象的

//addTypeDef方法,该方法的三个参数分别为:类型名称,类型实

//现类,类型参数,为Hibernate添加类型定义

ReflectionUtils.invokeMethod(addTypeDef, mappings,

typeDef.getTypeName(), typeDef.getTypeClass(), typeDef.getParameters());

}

}

//注册Hibernate过滤器

if (this.filterDefinitions != null) {

for (FilterDefinition filterDef : this.filterDefinitions) {

config.addFilterDefinition(filterDef);

}

}

//从给定资源路径加载Hibernate配置

if (this.configLocations != null) {

for (Resource resource : this.configLocations) {

config.configure(resource.getURL());

}

}

//添加Hibernate属性

if (this.hibernateProperties != null) {

config.addProperties(this.hibernateProperties);

}

//配置数据源

if (dataSource != null) {

//Spring中默认的Hibernate数据源连接提供类

Class providerClass = LocalDataSourceConnectionProvider.class;

//如果使用了事务包装数据源或者使用事务包装数据源代理,则使用

//TransactionAwareDataSourceConnectionProvider作为连接提供类

if (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy) {

providerClass = TransactionAwareDataSourceConnectionProvider.class;

}

//如果Hibernate配置文件中指定事务管理策略,则使用

//LocalJtaDataSourceConnectionProvider作为数据源连接提供类

else if (config.getProperty(Environment.TRANSACTION_MANAGER_STRATEGY) != null) {

providerClass = LocalJtaDataSourceConnectionProvider.class;

}

//设置Hibernate的数据源连接提供类

config.setProperty(Environment.CONNECTION_PROVIDER, providerClass.getName());

}

//如果Hibernate配置中指定了缓存区域工厂,则使用Spring提供的Hibernate

//缓存区域工厂

if (this.cacheRegionFactory != null) {

config.setProperty(Environment.CACHE_REGION_FACTORY,

"org.springframework.orm.hibernate3.LocalRegionFactoryProxy");

}

//如果Hibernate配置中指定了缓存提供类,则使用Spring提供的

//LocalCacheProviderProxy作为Hibernate缓存提供者

else if (this.cacheProvider != null) {

config.setProperty(Environment.CACHE_PROVIDER, LocalCacheProviderProxy.class.getName());

}

//如果Hibernate配置中指定了实体映射资源,则注册给定的Hibernate映射

if (this.mappingResources != null) {

//遍历给定的Hibernate映射资源

for (String mapping : this.mappingResources) {

//定位classpath中的Hibernate映射资源

Resource resource = new ClassPathResource(mapping.trim(), this.beanClassLoader);

//将Hibernate映射资源输入流添加到Hibernate配置输入流中

config.addInputStream(resource.getInputStream());

}

}

//如果Hibernate配置中指定了实体映射文件路径

if (this.mappingLocations != null) {

//遍历给定的路径,将Hibernate实体映射文件输入流添加到Hibernate

//配置输入流中

for (Resource resource : this.mappingLocations) {

config.addInputStream(resource.getInputStream());

}

}

//如果Hibernate配置中指定了缓存映射路径

if (this.cacheableMappingLocations != null) {

//将给定的缓存映射文件添加到Hibernate配置的缓存文件中

for (Resource resource : this.cacheableMappingLocations) {

config.addCacheableFile(resource.getFile());

}

}

//如果Hibernate配置中指定了包含在jar文件中的映射文件路径

if (this.mappingJarLocations != null) {

//将包含在jar文件中的映射文件添加到Hibernate配置中

for (Resource resource : this.mappingJarLocations) {

config.addJar(resource.getFile());

}

}

//如果Hibernate配置中指定了包含映射文件的目录路径

if (this.mappingDirectoryLocations != null) {

//将包含映射文件的给定目录添加到Hibernate配置中

for (Resource resource : this.mappingDirectoryLocations) {

File file = resource.getFile();

if (!file.isDirectory()) {

throw new IllegalArgumentException(

"Mapping directory location [" + resource + "] does not denote a directory");

}

config.addDirectory(file);

}

}

//编译Hibernate需要的映射信息

postProcessMappings(config);

config.buildMappings();

//如果Hibernate配置中指定了实体缓存策略

if (this.entityCacheStrategies != null) {

//为映射实体设置缓存策略

for (Enumeration classNames = this.entityCacheStrategies.propertyNames(); classNames.hasMoreElements();) {

String className = (String) classNames.nextElement();

//获取缓存策略属性值,将csv格式数据转换为字符串数组

String[] strategyAndRegion =

StringUtils.commaDelimitedListToStringArray(this.entityCacheStrategies.getProperty(className));

//如果缓存策略属性值多于2个,则只给Hibernate设置前两个值

if (strategyAndRegion.length > 1) {

//获取Hibernate配置中的setCacheConcurrencyStrategy方法

Method setCacheConcurrencyStrategy = Configuration.class.getMethod(

"setCacheConcurrencyStrategy", String.class, String.class, String.class);

//通过反射机制调用Hibernate配置对象的setCacheConcurrencyStrategy方法

ReflectionUtils.invokeMethod(setCacheConcurrencyStrategy, config,

className, strategyAndRegion[0], strategyAndRegion[1]);

}

//缓存策略属性值只有一个,则只需设置一个

else if (strategyAndRegion.length > 0) {

config.setCacheConcurrencyStrategy(className, strategyAndRegion[0]);

}

}

}

//如果Hibernate配置了集合缓存策略

if (this.collectionCacheStrategies != null) {

//为映射的集合注册缓存策略

for (Enumeration collRoles = this.collectionCacheStrategies.propertyNames(); collRoles.hasMoreElements();) {

String collRole = (String) collRoles.nextElement();

String[] strategyAndRegion =

StringUtils.commaDelimitedListToStringArray(this.collectionCacheStrategies.getProperty(collRole));

if (strategyAndRegion.length > 1) {

config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0], strategyAndRegion[1]);

}

else if (strategyAndRegion.length > 0) {

config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0]);

}

}

}

//注册Hibernate事件监听器

if (this.eventListeners != null) {

for (Map.Entry<String, Object> entry : this.eventListeners.entrySet()) {

//监听事件类型

String listenerType = entry.getKey();

//监听类对象

Object listenerObject = entry.getValue();

//如果监听类对象类型是集合

if (listenerObject instanceof Collection) {

Collection<Object> listeners = (Collection<Object>) listenerObject;

EventListeners listenerRegistry = config.getEventListeners();

//获取给定监听类型的所有监听类

Object[] listenerArray =

(Object[]) Array.newInstance(listenerRegistry.getListenerClassFor(listenerType), listeners.size());

listenerArray = listeners.toArray(listenerArray);

//Hibernate配置设置集合类型的监听类

config.setListeners(listenerType, listenerArray);

}

// Hibernate配置设置普通的监听类

else {

config.setListener(listenerType, listenerObject);

}

}

}

//Hibernate配置完成,客户自定义处理

postProcessConfiguration(config);

logger.info("Building new Hibernate SessionFactory");

this.configuration = config;

//根据Hibernate配置创建SessionFactory对象

return newSessionFactory(config);

}

//清空线程绑定的资源

finally {

if (dataSource != null) {

configTimeDataSourceHolder.remove();

}

if (this.jtaTransactionManager != null) {

configTimeTransactionManagerHolder.remove();

}

if (this.cacheRegionFactory != null) {

configTimeCacheProviderHolder.remove();

}

if (this.cacheProvider != null) {

configTimeCacheProviderHolder.remove();

}

if (this.lobHandler != null) {

configTimeLobHandlerHolder.remove();

}

if (overrideClassLoader) {

currentThread.setContextClassLoader(threadContextClassLoader);

}

}

}

//根据Hibernate配置创建SessionFactory

protected SessionFactory newSessionFactory(Configuration config) throws HibernateException {

return config.buildSessionFactory();

}

//创建Hibernate会话工厂protected SessionFactory buildSessionFactory() throws Exception { //获取Hibernate配置 Configuration config = newConfiguration(); //获取数据源 DataSource dataSource = getDataSource(); //配置数据源,事务管理器,缓存等等,将这些配置设置当对应的线程局部变量中, //使资源和当前线程绑定起来 if (dataSource != null) { //配置数据源 configTimeDataSourceHolder.set(dataSource); } if (this.jtaTransactionManager != null) { //配置jta事务管理器 configTimeTransactionManagerHolder.set(this.jtaTransactionManager); } if (this.cacheRegionFactory != null) { //配置缓存区域工厂 configTimeRegionFactoryHolder.set(this.cacheRegionFactory); } if (this.cacheProvider != null) { //配置缓存提供者 configTimeCacheProviderHolder.set(this.cacheProvider); } if (this.lobHandler != null) { //配置lob处理器,用于处理clob/blob等大字段类型映射 configTimeLobHandlerHolder.set(this.lobHandler); } //Hibernate不允许显示设置类加载器,因此需要暴露相应的线程上下文类加载器 Thread currentThread = Thread.currentThread(); ClassLoader threadContextClassLoader = currentThread.getContextClassLoader(); boolean overrideClassLoader = (this.beanClassLoader != null && !this.beanClassLoader.equals(threadContextClassLoader)); //用当前类加载器覆盖当前线程上下文类加载器 if (overrideClassLoader) { currentThread.setContextClassLoader(this.beanClassLoader); } //配置Hibernate相关属性 try { //如果Hibernate会话工厂暴露一个会话包装的代理 if (isExposeTransactionAwareSessionFactory()) { //使用Spring管理的Session作为Hibernate当前会话 config.setProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName()); } //如果Hibernate会话工厂指定了事务管理器,则使用Hibernate的事务管理器 if (this.jtaTransactionManager != null) { config.setProperty( Environment.TRANSACTION_STRATEGY, JTATransactionFactory.class.getName()); config.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.class.getName()); } //如果Hibernate会话工厂没有指定事务管理器,则使用Spring管理的事务 else { config.setProperty( Environment.TRANSACTION_STRATEGY, SpringTransactionFactory.class.getName()); } //设置SessionFactory级别的实体拦截器 if (this.entityInterceptor != null) { config.setInterceptor(this.entityInterceptor); } //设置命名规则 if (this.namingStrategy != null) { config.setNamingStrategy(this.namingStrategy); } //注册指定的Hibernate类型定义 if (this.typeDefinitions != null) { //通过JDK反射机制,获取Hibernate配置文件中的createMappings方法 Method createMappings = Configuration.class.getMethod("createMappings");//通过JDK反射,获取createMappings方法返回的org.hibernate.cfg.Mappings对//象的addTypeDef方法,该方法的三个参数类型为:String,String和Properties Method addTypeDef = createMappings.getReturnType().getMethod( "addTypeDef", String.class, String.class, Properties.class); //通过JDK反射机制调用Hibernate配置中的createMappings方法, //返回org.hibernate.cfg.Mappings对象 Object mappings = ReflectionUtils.invokeMethod(createMappings, config); //遍历Hibernate中所有注册的类型定义 for (TypeDefinitionBean typeDef : this.typeDefinitions) { //通过反射机制,调用org.hibernate.cfg.Mappings对象的 //addTypeDef方法,该方法的三个参数分别为:类型名称,类型实//现类,类型参数,为Hibernate添加类型定义 ReflectionUtils.invokeMethod(addTypeDef, mappings, typeDef.getTypeName(), typeDef.getTypeClass(), typeDef.getParameters()); } } //注册Hibernate过滤器 if (this.filterDefinitions != null) { for (FilterDefinition filterDef : this.filterDefinitions) { config.addFilterDefinition(filterDef); } } //从给定资源路径加载Hibernate配置 if (this.configLocations != null) { for (Resource resource : this.configLocations) { config.configure(resource.getURL()); } } //添加Hibernate属性 if (this.hibernateProperties != null) { config.addProperties(this.hibernateProperties); } //配置数据源 if (dataSource != null) { //Spring中默认的Hibernate数据源连接提供类 Class providerClass = LocalDataSourceConnectionProvider.class; //如果使用了事务包装数据源或者使用事务包装数据源代理,则使用 //TransactionAwareDataSourceConnectionProvider作为连接提供类 if (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy) { providerClass = TransactionAwareDataSourceConnectionProvider.class; } //如果Hibernate配置文件中指定事务管理策略,则使用 //LocalJtaDataSourceConnectionProvider作为数据源连接提供类 else if (config.getProperty(Environment.TRANSACTION_MANAGER_STRATEGY) != null) { providerClass = LocalJtaDataSourceConnectionProvider.class; } //设置Hibernate的数据源连接提供类 config.setProperty(Environment.CONNECTION_PROVIDER, providerClass.getName()); } //如果Hibernate配置中指定了缓存区域工厂,则使用Spring提供的Hibernate //缓存区域工厂 if (this.cacheRegionFactory != null) { config.setProperty(Environment.CACHE_REGION_FACTORY, "org.springframework.orm.hibernate3.LocalRegionFactoryProxy"); } //如果Hibernate配置中指定了缓存提供类,则使用Spring提供的 //LocalCacheProviderProxy作为Hibernate缓存提供者 else if (this.cacheProvider != null) { config.setProperty(Environment.CACHE_PROVIDER, LocalCacheProviderProxy.class.getName()); } //如果Hibernate配置中指定了实体映射资源,则注册给定的Hibernate映射 if (this.mappingResources != null) { //遍历给定的Hibernate映射资源 for (String mapping : this.mappingResources) { //定位classpath中的Hibernate映射资源 Resource resource = new ClassPathResource(mapping.trim(), this.beanClassLoader); //将Hibernate映射资源输入流添加到Hibernate配置输入流中 config.addInputStream(resource.getInputStream()); } } //如果Hibernate配置中指定了实体映射文件路径 if (this.mappingLocations != null) { //遍历给定的路径,将Hibernate实体映射文件输入流添加到Hibernate //配置输入流中 for (Resource resource : this.mappingLocations) { config.addInputStream(resource.getInputStream()); } } //如果Hibernate配置中指定了缓存映射路径 if (this.cacheableMappingLocations != null) { //将给定的缓存映射文件添加到Hibernate配置的缓存文件中 for (Resource resource : this.cacheableMappingLocations) { config.addCacheableFile(resource.getFile()); } } //如果Hibernate配置中指定了包含在jar文件中的映射文件路径 if (this.mappingJarLocations != null) { //将包含在jar文件中的映射文件添加到Hibernate配置中 for (Resource resource : this.mappingJarLocations) { config.addJar(resource.getFile()); } } //如果Hibernate配置中指定了包含映射文件的目录路径 if (this.mappingDirectoryLocations != null) { //将包含映射文件的给定目录添加到Hibernate配置中 for (Resource resource : this.mappingDirectoryLocations) { File file = resource.getFile(); if (!file.isDirectory()) { throw new IllegalArgumentException( "Mapping directory location [" + resource + "] does not denote a directory"); } config.addDirectory(file); } } //编译Hibernate需要的映射信息 postProcessMappings(config); config.buildMappings(); //如果Hibernate配置中指定了实体缓存策略 if (this.entityCacheStrategies != null) { //为映射实体设置缓存策略 for (Enumeration classNames = this.entityCacheStrategies.propertyNames(); classNames.hasMoreElements();) { String className = (String) classNames.nextElement(); //获取缓存策略属性值,将csv格式数据转换为字符串数组 String[] strategyAndRegion = StringUtils.commaDelimitedListToStringArray(this.entityCacheStrategies.getProperty(className)); //如果缓存策略属性值多于2个,则只给Hibernate设置前两个值 if (strategyAndRegion.length > 1) {//获取Hibernate配置中的setCacheConcurrencyStrategy方法 Method setCacheConcurrencyStrategy = Configuration.class.getMethod( "setCacheConcurrencyStrategy", String.class, String.class, String.class); //通过反射机制调用Hibernate配置对象的setCacheConcurrencyStrategy方法 ReflectionUtils.invokeMethod(setCacheConcurrencyStrategy, config, className, strategyAndRegion[0], strategyAndRegion[1]); } //缓存策略属性值只有一个,则只需设置一个 else if (strategyAndRegion.length > 0) { config.setCacheConcurrencyStrategy(className, strategyAndRegion[0]); } } } //如果Hibernate配置了集合缓存策略 if (this.collectionCacheStrategies != null) { //为映射的集合注册缓存策略 for (Enumeration collRoles = this.collectionCacheStrategies.propertyNames(); collRoles.hasMoreElements();) { String collRole = (String) collRoles.nextElement(); String[] strategyAndRegion = StringUtils.commaDelimitedListToStringArray(this.collectionCacheStrategies.getProperty(collRole)); if (strategyAndRegion.length > 1) { config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0], strategyAndRegion[1]); } else if (strategyAndRegion.length > 0) { config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0]); } } } //注册Hibernate事件监听器 if (this.eventListeners != null) { for (Map.Entry<String, Object> entry : this.eventListeners.entrySet()) { //监听事件类型 String listenerType = entry.getKey(); //监听类对象 Object listenerObject = entry.getValue(); //如果监听类对象类型是集合 if (listenerObject instanceof Collection) { Collection<Object> listeners = (Collection<Object>) listenerObject; EventListeners listenerRegistry = config.getEventListeners(); //获取给定监听类型的所有监听类 Object[] listenerArray = (Object[]) Array.newInstance(listenerRegistry.getListenerClassFor(listenerType), listeners.size()); listenerArray = listeners.toArray(listenerArray); //Hibernate配置设置集合类型的监听类 config.setListeners(listenerType, listenerArray); } // Hibernate配置设置普通的监听类 else { config.setListener(listenerType, listenerObject); } } } //Hibernate配置完成,客户自定义处理 postProcessConfiguration(config); logger.info("Building new Hibernate SessionFactory"); this.configuration = config; //根据Hibernate配置创建SessionFactory对象 return newSessionFactory(config); } //清空线程绑定的资源 finally { if (dataSource != null) { configTimeDataSourceHolder.remove(); } if (this.jtaTransactionManager != null) { configTimeTransactionManagerHolder.remove(); } if (this.cacheRegionFactory != null) { configTimeCacheProviderHolder.remove(); } if (this.cacheProvider != null) { configTimeCacheProviderHolder.remove(); } if (this.lobHandler != null) { configTimeLobHandlerHolder.remove(); } if (overrideClassLoader) { currentThread.setContextClassLoader(threadContextClassLoader); } } }//根据Hibernate配置创建SessionFactoryprotected SessionFactory newSessionFactory(Configuration config) throws HibernateException { return config.buildSessionFactory(); } 上述代码非常的长,但是所做的工作非常的清楚,即获取Hibernate的配置,然后设置Hibernate配置,最后生成SessionFactory的过程。 4.HibernateTemplate实现: 和Spring对jdbc封装类似,Spring使用HibernateTemplate对Hibernate也进行了一下API封装,通过execute回调来调用Hibernate的相关操作处理,接下来简单分析HibernateTemplate的核心实现。 (1). execute相关方法的实现: 与JdbcTemplate类似,execute相关方法也是HibernateTemplate的基础核心方法,在execute相关方法中,Spring提供获取Hibernate Session,为当前的Session进行事务处理等通用的操作,源码如下: [java] view plaincopyprint? //最基础的execute方法

public <T> T execute(HibernateCallback<T> action) throws DataAccessException {

return doExecute(action, false, false);

}

//需要在新的Hibernate Session中执行的execute方法

public <T> T executeWithNewSession(HibernateCallback<T> action) {

return doExecute(action, true, false);

}

//需要在Hibernate本地Session中执行的execute方法

public <T> T executeWithNativeSession(HibernateCallback<T> action) {

return doExecute(action, false, true);

}

//真正调用Hibernate API的地方

protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession)

throws DataAccessException {

Assert.notNull(action, "Callback object must not be null");

//获取Hibernate会话,判断是否需要新的Session

Session session = (enforceNewSession ?

SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession());

//是否存在事务

boolean existingTransaction = (!enforceNewSession &&

(!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory())));

if (existingTransaction) {

logger.debug("Found thread-bound Session for HibernateTemplate");

}

//刷新模式

FlushMode previousFlushMode = null;

try {

//根据Hibernate Session和事务类型应用相应的刷新模式

previousFlushMode = applyFlushMode(session, existingTransaction);

//对Session开启过滤器

enableFilters(session);

//判断Hibernate Session是否需要代理包装

Session sessionToExpose =

(enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session));

//对HibernateCallBack中回调函数的调用,真正调用Hibernate API

T result = action.doInHibernate(sessionToExpose);

flushIfNecessary(session, existingTransaction);

return result;

}

catch (HibernateException ex) {

throw convertHibernateAccessException(ex);

}

catch (SQLException ex) {

throw convertJdbcAccessException(ex);

}

catch (RuntimeException ex) {

throw ex;

}

finally {

//如果存在事务,则调用完毕之后不关闭Session

if (existingTransaction) {

logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");

//对Session禁用过滤器

disableFilters(session);

if (previousFlushMode != null) {

session.setFlushMode(previousFlushMode);

}

}

//如果不存在事务,则关闭当前的Session

else {

if (isAlwaysUseNewSession()) {

SessionFactoryUtils.closeSession(session);

}

else {

SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());

}

}

}

}

//最基础的execute方法public <T> T execute(HibernateCallback<T> action) throws DataAccessException { return doExecute(action, false, false); } //需要在新的Hibernate Session中执行的execute方法public <T> T executeWithNewSession(HibernateCallback<T> action) { return doExecute(action, true, false); } //需要在Hibernate本地Session中执行的execute方法public <T> T executeWithNativeSession(HibernateCallback<T> action) { return doExecute(action, false, true); } //真正调用Hibernate API的地方protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); //获取Hibernate会话,判断是否需要新的Session Session session = (enforceNewSession ? SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession()); //是否存在事务 boolean existingTransaction = (!enforceNewSession && (!isAllowCreate() || SessionFactoryUtils.isSessionTransactional(session, getSessionFactory()))); if (existingTransaction) { logger.debug("Found thread-bound Session for HibernateTemplate"); } //刷新模式 FlushMode previousFlushMode = null; try { //根据Hibernate Session和事务类型应用相应的刷新模式 previousFlushMode = applyFlushMode(session, existingTransaction); //对Session开启过滤器 enableFilters(session); //判断Hibernate Session是否需要代理包装 Session sessionToExpose = (enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session)); //对HibernateCallBack中回调函数的调用,真正调用Hibernate API T result = action.doInHibernate(sessionToExpose); flushIfNecessary(session, existingTransaction); return result; } catch (HibernateException ex) { throw convertHibernateAccessException(ex); } catch (SQLException ex) { throw convertJdbcAccessException(ex); } catch (RuntimeException ex) { throw ex; } finally { //如果存在事务,则调用完毕之后不关闭Session if (existingTransaction) { logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate"); //对Session禁用过滤器 disableFilters(session); if (previousFlushMode != null) { session.setFlushMode(previousFlushMode); } } //如果不存在事务,则关闭当前的Session else { if (isAlwaysUseNewSession()) { SessionFactoryUtils.closeSession(session); } else { SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory()); } } } } (2).HibernateTemplate中增删改查操作的简单实现: 以查询为例,分析HibernateTemplate如何通过execute方法回调Hibernate相应的API,源码如下: [java] view plaincopyprint? //查询指定Id的实体

public Object get(String entityName, Serializable id) throws DataAccessException {

return get(entityName, id, null);

}

//真正调用Hibernate API查询的方法

public Object get(final String entityName, final Serializable id, final LockMode lockMode)

throws DataAccessException {

//调用Hibernate本地查询方法,参数是一个实现HibernateCallback接口的

//匿名内部类,用于execute方法回调

return executeWithNativeSession(new HibernateCallback<Object>() {

//execute方法回调,真正调用Hibernate查询的方法

public Object doInHibernate(Session session) throws HibernateException {

if (lockMode != null) {

return session.get(entityName, id, lockMode);

}

else {

return session.get(entityName, id);

}

}

});

}

//查询指定Id的实体public Object get(String entityName, Serializable id) throws DataAccessException { return get(entityName, id, null); }//真正调用Hibernate API查询的方法public Object get(final String entityName, final Serializable id, final LockMode lockMode) throws DataAccessException { //调用Hibernate本地查询方法,参数是一个实现HibernateCallback接口的 //匿名内部类,用于execute方法回调 return executeWithNativeSession(new HibernateCallback<Object>() { //execute方法回调,真正调用Hibernate查询的方法 public Object doInHibernate(Session session) throws HibernateException { if (lockMode != null) { return session.get(entityName, id, lockMode); } else { return session.get(entityName, id); } } }); } 其他的load,update等等调用Hibernate的方法类似,各自提供不同的HibernateCallback回调来真正调用Hibernate相应方法。 5.Hibernate管理Session: 在4分析HibernateTemplate的doExecute法源码时我们看到,Spring根据是否需要新Session的判断,使用getSession和getNewSession两种不同的获取Session的方法,Spring中通过SessionFactoryUtils来管理HibernateSession,分析SessionFactoryUtils管理Session的实现源码: (1).getNewSession实现: [java] view plaincopyprint? //获取新Session

public static Session getNewSession(SessionFactory sessionFactory, Interceptor entityInterceptor) {

Assert.notNull(sessionFactory, "No SessionFactory specified");

try {

//获取事务管理器中的sessionFactory线程局部变量

SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);

//如果当前线程绑定了SessionFactory资源

if (sessionHolder != null && !sessionHolder.isEmpty()) {

//如果有实体拦截器,则打开一个有实体拦截器的Session连接

if (entityInterceptor != null) {

return sessionFactory.openSession(sessionHolder.getAnySession().connection(), entityInterceptor);

}

//如果没有实体拦截器,则直接打开当前线程中绑定的Session连接

else {

return sessionFactory.openSession(sessionHolder.getAnySession().connection());

}

}

//如果当前线程没有绑定SessionFactory资源

else {

//如果有实体拦截器

if (entityInterceptor != null) {

//打开一个包含给定实体拦截器的Session

return sessionFactory.openSession(entityInterceptor);

}

//如果没有实体拦截器,则直接打开一个新的Session

else {

return sessionFactory.openSession();

}

}

}

catch (HibernateException ex) {

throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);

}

}

//获取新Sessionpublic static Session getNewSession(SessionFactory sessionFactory, Interceptor entityInterceptor) { Assert.notNull(sessionFactory, "No SessionFactory specified"); try { //获取事务管理器中的sessionFactory线程局部变量 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); //如果当前线程绑定了SessionFactory资源 if (sessionHolder != null && !sessionHolder.isEmpty()) { //如果有实体拦截器,则打开一个有实体拦截器的Session连接 if (entityInterceptor != null) { return sessionFactory.openSession(sessionHolder.getAnySession().connection(), entityInterceptor); } //如果没有实体拦截器,则直接打开当前线程中绑定的Session连接 else { return sessionFactory.openSession(sessionHolder.getAnySession().connection()); } } //如果当前线程没有绑定SessionFactory资源 else { //如果有实体拦截器 if (entityInterceptor != null) { //打开一个包含给定实体拦截器的Session return sessionFactory.openSession(entityInterceptor); } //如果没有实体拦截器,则直接打开一个新的Session else { return sessionFactory.openSession(); } } } catch (HibernateException ex) { throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); } } (2).getSession实现: [java] view plaincopyprint? //获取Hibernate Session的入口方法

public static Session getSession(SessionFactory sessionFactory, boolean allowCreate)

throws DataAccessResourceFailureException, IllegalStateException {

try {

//通过调用doGetSession来获取Hibernate Session

return doGetSession(sessionFactory, null, null, allowCreate);

}

catch (HibernateException ex) {

throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);

}

}

//获取Hibernate Session

private static Session doGetSession(

SessionFactory sessionFactory, Interceptor entityInterceptor,

SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)

throws HibernateException, IllegalStateException {

Assert.notNull(sessionFactory, "No SessionFactory specified");

//获取和当前线程绑定的Session资源

SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);

//如果当前线程有绑定了Session的资源,即已经有创建了的Session

if (sessionHolder != null && !sessionHolder.isEmpty()) {

Session session = null;

//如果Spring事务管理是activate的

if (TransactionSynchronizationManager.isSynchronizationActive() &&

sessionHolder.doesNotHoldNonDefaultSession()) {

//获取当前线程绑定的有效Session

session = sessionHolder.getValidatedSession();

//如果获取了当前线程绑定的有效Session,并且当前线程绑定的Session

//资源是事务同步的

if (session != null && !sessionHolder.isSynchronizedWithTransaction()) {

logger.debug("Registering Spring transaction synchronization for existing Hibernate Session");

//为已有的Hibernate Session注册Spring事务同步

TransactionSynchronizationManager.registerSynchronization(

new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false));

sessionHolder.setSynchronizedWithTransaction(true);

//根据实现级别设置Session刷新模式

FlushMode flushMode = session.getFlushMode();

if (flushMode.lessThan(FlushMode.COMMIT) &&

!TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {

session.setFlushMode(FlushMode.AUTO);

sessionHolder.setPreviousFlushMode(flushMode);

}

}

}

//如果没有Spring管理的事务

else {

//使用jta事务同步

session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator);

}

if (session != null) {

return session;

}

}

logger.debug("Opening Hibernate Session");

//当前线程没有绑定Session资源,则需要创建新Session

Session session = (entityInterceptor != null ?

sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession());

//如果Spring管理的事务是activate的

if (TransactionSynchronizationManager.isSynchronizationActive()) {

logger.debug("Registering Spring transaction synchronization for new Hibernate Session");

SessionHolder holderToUse = sessionHolder;

//将新创建的Session添加到当前线程局部变量中

if (holderToUse == null) {

holderToUse = new SessionHolder(session);

}

else {

holderToUse.addSession(session);

}

//设置Session刷新模式

if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {

session.setFlushMode(FlushMode.MANUAL);

}

//为新创建的Hibernate Session注册Spring事务

TransactionSynchronizationManager.registerSynchronization(

new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true));

holderToUse.setSynchronizedWithTransaction(true);

//将新创建的Session与当前线资源程绑定

if (holderToUse != sessionHolder) {

TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse);

}

}

//如果没有Spring事务

else {

//为Session设置JTA事务

registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder);

}

//判断是否允许返回给定的Session

if (!allowCreate && !isSessionTransactional(session, sessionFactory)) {

closeSession(session);

throw new IllegalStateException("No Hibernate Session bound to thread, " +

"and configuration does not allow creation of non-transactional one here");

}

return session;

}

//获取Hibernate Session的入口方法public static Session getSession(SessionFactory sessionFactory, boolean allowCreate) throws DataAccessResourceFailureException, IllegalStateException { try { //通过调用doGetSession来获取Hibernate Session return doGetSession(sessionFactory, null, null, allowCreate); } catch (HibernateException ex) { throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); } } //获取Hibernate Sessionprivate static Session doGetSession( SessionFactory sessionFactory, Interceptor entityInterceptor, SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate) throws HibernateException, IllegalStateException { Assert.notNull(sessionFactory, "No SessionFactory specified"); //获取和当前线程绑定的Session资源 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); //如果当前线程有绑定了Session的资源,即已经有创建了的Session if (sessionHolder != null && !sessionHolder.isEmpty()) { Session session = null; //如果Spring事务管理是activate的 if (TransactionSynchronizationManager.isSynchronizationActive() && sessionHolder.doesNotHoldNonDefaultSession()) { //获取当前线程绑定的有效Session session = sessionHolder.getValidatedSession(); //如果获取了当前线程绑定的有效Session,并且当前线程绑定的Session //资源是事务同步的 if (session != null && !sessionHolder.isSynchronizedWithTransaction()) { logger.debug("Registering Spring transaction synchronization for existing Hibernate Session");//为已有的Hibernate Session注册Spring事务同步 TransactionSynchronizationManager.registerSynchronization( new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false)); sessionHolder.setSynchronizedWithTransaction(true); //根据实现级别设置Session刷新模式 FlushMode flushMode = session.getFlushMode(); if (flushMode.lessThan(FlushMode.COMMIT) && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { session.setFlushMode(FlushMode.AUTO); sessionHolder.setPreviousFlushMode(flushMode); } } } //如果没有Spring管理的事务 else { //使用jta事务同步 session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator); } if (session != null) { return session; } } logger.debug("Opening Hibernate Session"); //当前线程没有绑定Session资源,则需要创建新Session Session session = (entityInterceptor != null ? sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession()); //如果Spring管理的事务是activate的 if (TransactionSynchronizationManager.isSynchronizationActive()) { logger.debug("Registering Spring transaction synchronization for new Hibernate Session"); SessionHolder holderToUse = sessionHolder; //将新创建的Session添加到当前线程局部变量中 if (holderToUse == null) { holderToUse = new SessionHolder(session); } else { holderToUse.addSession(session); } //设置Session刷新模式 if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { session.setFlushMode(FlushMode.MANUAL); } //为新创建的Hibernate Session注册Spring事务 TransactionSynchronizationManager.registerSynchronization( new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true)); holderToUse.setSynchronizedWithTransaction(true); //将新创建的Session与当前线资源程绑定 if (holderToUse != sessionHolder) { TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse); } } //如果没有Spring事务 else { //为Session设置JTA事务 registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder); } //判断是否允许返回给定的Session if (!allowCreate && !isSessionTransactional(session, sessionFactory)) { closeSession(session); throw new IllegalStateException("No Hibernate Session bound to thread, " + "and configuration does not allow creation of non-transactional one here"); } return session; } 通过上面Spring对Hibernate Session管理的源码分析,我们了解到Spring已经将Hibernate Session的获取与关闭,Session的事务处理,以及Session与线程资源绑定等操作做了封装统一管理,为应用使用Hibernate提供了方便。

推荐:SSH框架学习(四、在struts和spring基础上加入hibernate)

原文转自:http://blog.csdn.net/wuyt2008/article/details/8243544 Hibernate有很机械的pojo类和hbm文件要写,这部分用myeclipse来做,能省不少事情,终于又感

1.Spring中,不提供具体的ORM实现,而只是为应用提供对ORM产品的集成环境和使用平台,Spring将Hibernate的会话工厂通过IoC容器管理起来,并且将数据源注入,同时Spring为Hibernate提供了更上层

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。