1、Spring中,不提供具体的ORM实现,而只是为应用提供对ORM产品的集成环境和使用平台,Spring将Hibernate的会话工厂通过IoC容器管理起来,并且将数据源注入,同时Spring为Hibernate提供了更为上层的API封装,方便应用调用,本文通过分析相应源码了解Spring对Hibernate支持的实现。
2、AbstractSessionFactoryBean管理Hibernate会话工厂:
Hibernate的SessionFactory(会话工厂)是Hibernate的基础,SessionFactory管理Hibernate的相关配置和映射资源,Spring中通过AbstractSessionFactoryBean抽象类来管理Hibernate的会话工厂,AbstractSessionFactoryBean实现Spring的工厂Bean(FactoryBean)接口,因此AbstractSessionFactoryBean是一个Spring的工厂Bean,即Spring管理Hibernate的IoC容器,AbstractSessionFactoryBean的源码如下:
public abstract class AbstractSeesionFactoryBean implements FactoryBean<SessionFactory>,InitializingBean,DisposableBean,PersistenceExceptionTranslator {
protected final Log logger = LogFactory.get(getClass());
//数据源
private DataSource dataSource;
//Hibernate会话使用Spring事务管理器包装的数据源
private boolean useTransactionAwareDataSource = false;
//从Hibernate会话工厂中获取的当前会话是否暴露给Spring事务来包装
private boolean exposeTransactionAwareSessionFactory = true;
//Hibernate SQL相关异常转换器
private SQLExceptionTranlator 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> getObject() {
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异常类型,则使用Hibernat默认的异常转换器转换
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方法创建单态模式的Hibernate会话工厂。
(2)应用通过getObject方法向Spring管理Hibernate会话工厂的IoC容器AbstractSessionFactoryBean索取Hibernate会话工厂。
下面我们继续分析AbstractSessionFactoryBean子类LocalSessionFactoryBean创建Hibernate会话工厂的过程。
3、LocalSessionFactoryBean创建SessionFactory:
Spring中管理Hibernate会话工厂的IoC容器AbstractSessionFactoryBean通过委派模式调用其子类LocalSessionFactoryBean的buildSessionFactory创建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){
//配置缓提供者
configTimeLobHandlerHolder.set(this.lobHandler);
}
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,JTATransanctionFactory.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添加类
//型定义
ReflectUtils.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(ths.mappingJarLocations != null){
//将包含在jar文件中的映射文件添加到Hibernate配置中
for(Resource resource : this.mappingJarLocaitons){
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 HiberanteException {
return config.buildSessionFactory();
}
上述代码非常的长,但是所做的工作非常清楚,即获取Hibernate配置,然后设置Hibernate配置,最后生成SessionFactory的过程。
4、HibernateTemplate实现:
和Spring对jdbc封装类似,Spring使用HibernateTemplate对Hibernate也进行了一些API封装,通过execute回调来调用Hibernate的相关操作处理,接下来简单分析Hibernate的核心实现。
(1)execute相关方法的实现:
与JdbcTemplate类似,execute相关方法也是HibernateTemplate的基础核心方法,在execute相关方法中,Spring通过获取Hiberate 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){
retun 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() || SessionFactoryUtis.isSessionTransactionnl(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 = aciton.doInHibernate(sessionToExpose);
flushIfNecessary(session,existingTransaction);
return result;
}
catch(HiernateException 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);
}
}
});
}
其他的load,update等等调用Hibernate的方法类似,各自提供不同的HibernateCallback回调来真正调用Hibernate相应方法。
5、Hibernate管理Session:
在4分析HibernateTemplate的doExecute源码时我们看到,Spring根据是否需要新Session的判断,使用getSession和getNewSession两种不同的获取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.openSesson(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来获取Hibernat 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,IllegalStateExcepion {
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.isSynchronizationAcitve() && sessionHoler.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事务同步
TransactionSynchronizationMapper.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管理的事务是active的
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提供了方便。