《Spring技术内幕》学习笔记12——HibernateTemplate对Hibernate的封装

1.Spring中,不提供具体的ORM实现,而只是为应用提供对ORM产品的集成环境和使用平台,SpringHibernate的会话工厂通过IoC容器管理起来,并且将数据源注入,同时SpringHibernate提供了更上层的API封装,方便应用调用,本文通过分析相应源码了解SpringHibernate支持的实现。

2.AbstractSessionFactoryBean管理Hibernate会话工厂:

使用过Hibernate的人都知道,HibernateSessionFactory(会话工厂)Hibernate的基础,SessionFactory管理Hibernate的相关配置和映射资源,Spring中通过AbstractSessionFactoryBean抽象类来管理Hibernate的会话工厂,AbstractSessionFactoryBean实现Spring的工厂Bean(FactoryBean)接口,因此AbstractSessionFactoryBean是一个Spring的工厂Bean,即Spring管理HibernateIoC容器,AbstractSessionFactoryBean的源码如下:

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() { } }

通过分析SpringHibernate会话工厂管理的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通过委派模式调用其子类LocalSessionFactoryBeanbuildSessionFactory创建Hibernate会话工厂,源码如下:

//创建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的配置,然后设置Hibernate配置,最后生成SessionFactory的过程。

4.HibernateTemplate实现:

Springjdbc封装类似,Spring使用HibernateTemplateHibernate也进行了一下API封装,通过execute回调来调用Hibernate的相关操作处理,接下来简单分析HibernateTemplate的核心实现。

(1). execute相关方法的实现:

JdbcTemplate类似,execute相关方法也是HibernateTemplate的基础核心方法,在execute相关方法中,Spring提供获取Hibernate Session,为当前的Session进行事务处理等通用的操作,源码如下:

//最基础的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,源码如下:

//查询指定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); } } }); }

其他的loadupdate等等调用Hibernate的方法类似,各自提供不同的HibernateCallback回调来真正调用Hibernate相应方法。

5.Hibernate管理Session

4分析HibernateTemplatedoExecute法源码时我们看到,Spring根据是否需要新Session的判断,使用getSessiongetNewSession两种不同的获取Session的方法,Spring中通过SessionFactoryUtils来管理HibernateSession,分析SessionFactoryUtils管理Session的实现源码:

(1).getNewSession实现:

//获取新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); } }

(2).getSession实现:

//获取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; }

通过上面SpringHibernate Session管理的源码分析,我们了解到Spring已经将Hibernate Session的获取与关闭,Session的事务处理,以及Session与线程资源绑定等操作做了封装统一管理,为应用使用Hibernate提供了方便。

你可能感兴趣的:(spring,Hibernate,session,jdbc,IOC,null)