spring技术内幕12-HibernateTemplate对Hibernate的封装

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提供了方便。

    

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值