原文链接http://blog.csdn.net/chjttony/article/details/6415290
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的源码如下:
- 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会话工厂,源码如下:
- //创建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实现:
和Spring对jdbc封装类似,Spring使用HibernateTemplate对Hibernate也进行了一下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);
- }
- }
- });
- }
其他的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.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;
- }
通过上面Spring对Hibernate Session管理的源码分析,我们了解到Spring已经将Hibernate Session的获取与关闭,Session的事务处理,以及Session与线程资源绑定等操作做了封装统一管理,为应用使用Hibernate提供了方便。