博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate4.0之HibernateSessionFactory源码详解
阅读量:5949 次
发布时间:2019-06-19

本文共 5326 字,大约阅读时间需要 17 分钟。

import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;@SuppressWarnings("deprecation")public class HibernateSessionFactory {    /**      * Location of hibernate.cfg.xml file.     * Location should be on the classpath as Hibernate uses       * #resourceAsStream style lookup for its configuration file.      * The default classpath location of the hibernate config file is      * in the default package. Use #setConfigFile() to update      * the location of the configuration file for the current session.        */        private static String CONFIG_FIEL_LOACTION = "/hibernate.cfg.xml";    private static String configFile = CONFIG_FIEL_LOACTION;    private static final ThreadLocal
threadLocal = new ThreadLocal
(); private static org.hibernate.SessionFactory sessionFactory; private static Configuration configuration = new Configuration(); private static ServiceRegistry serviceRegistry; /** 在回话工厂类HibernateSessionFactory中, 首先通过一次静态代码块来启动Hibernate,该代码块只在HibernateSessionFactory类被加载时执行一次,用于建立sessionFactory。即SessionFactory是线程安全的,只能被实例化一次。在静态代码块中通过创建Configuration对象并调用其configure()方法读取Hibernate配置文件hibernate.cfg.xml信息,从而进行配置信息的管理。然后创建SessionFactory实例,在Hibernate4.0版本之前,该实例创建工作由Configuration对象的buildSessionFactory()方法来完成。而Hibernater4.0版本之后,创建SessionFactory实例的方法有所改变,Hibernate 增加了一个注册ServiceRegistryBuilder类。要生成一个注册机对象,然后所有的生成SessionFactory的对象向注册机注册一下再使用。生成方法还config.buildSessionFactory()方法,只不过加了一个注册机的参数。*/ static { try { configuration.configure(); serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%" + e); e.printStackTrace(); } } private HibernateSessionFactory() { } /** * Returns the ThreadLocal Session instance. Lazy initialize * the
SessionFactory if needed. * * 由于sessionFactory是线程安全的,因而同一个SessionFactory实例可以被多个线程共享,即多个并发线程可以同时访问一个SesisonFactory并 * 获得Session的实例。但由于Session不是线程安全的,如果多个并发线程同时操作同一个Session对象,就可能出现一个线程在进行数据库操作,而另一个 * 线程将Session对象关闭的情况,从而出现异常。如何才能保证线程安全呢?这就要求SessionFactory能够针对不同的线程创建不同的Session对象,即 * 需要对Session进行有效的管理,Hibernate中使用ThreadLocal对象来维护和管理Session实例。 * * ThreadLocal是线程局部变量,线程局部变量高效的为每一个使用它的线程提供单独的线程局部变量的副本。为了实现为每个线程维护一个变量的副本,ThreadLocal * 类提供了一个Map结构,是key值用来保存线程的ID, value用来保存一个Session实例的副本。这样多线程并发操作时,实在与自己绑定的Session实例副本上进行 * 的,从而避免多个线程横在同一个Session实例上操作是可能导致的数据异常。 * * 在HibernaterSessionFctory类的getSession()方法中,首先调用ThreadLocal类的get()方法获得当前线程的Session对象,然后判断当前线程是否已存在 * Session对象或者对象未打开,在判断SessionFactory对象是否为空,如果SeesionFctory对象不存在,先调用rebuildSessionFactory()方法创建SesionFactory, * 如果SessionFactory对象已经存在,则调用SessionFactory对象的openSession()方法创建Session对象。创建完Session对象后,还需要调用ThreadLocal的set() * 方法为该线程保存Session对象。 * * @return Session * @throws HibernateException */ public static Session getSession() { Session session = (Session) threadLocal.get(); try{ if (session == null || !session.isOpen()) { if (sessionFactory == null) { rebuildSessionFactory(); } session = (sessionFactory != null) ? sessionFactory.openSession() : null; threadLocal.set(session); } } catch (HibernateException e){ System.err.println("%%%% Error Creating getSession %%%%" + e); e.printStackTrace(); } return session; } /** * Rebuild hibernate session factory * */ public static void rebuildSessionFactory() { synchronized(sessionFactory){ try { configuration.configure(configFile); serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); } catch (Exception e) { System.err.println("%%%% Error rebuildSessionFactory %%%%" + e); e.printStackTrace(); } } } /** * Close the single hibernate session instance. * * @throws HibernateException */ public static void closeSession(){ Session session = (Session) threadLocal.get(); threadLocal.set(null); try{ if (session != null && session.isOpen()) { session.close(); } } catch(HibernateException e){ System.err.println("%%%% Error closeSession %%%%" + e); e.printStackTrace(); } } /** * return session factory * */ public static org.hibernate.SessionFactory getSessionFactory() { return sessionFactory; } /** * return hibernate configuration * */ public static Configuration getConfiguration() { return configuration; } public static void setConfigFile(String configFile){ HibernateSessionFactory.configFile = configFile; }}

 

转载地址:http://rddxx.baihongyu.com/

你可能感兴趣的文章
TCP服务器端口转发: netsh
查看>>
PhoneGap入门经典——理解PhoneGap应用程序基础
查看>>
2016OSC源创会年终盛典-架构与数据专场-张千明
查看>>
nginx实现rtmp,flv,mp4流媒体服务器
查看>>
46.tornado绑定域名或者子域名泛域名的处理
查看>>
Elasticsearch 2.2.0 节点发现详解
查看>>
Elasticsearch 2.2.0 插件篇:安装
查看>>
文本过滤--sed 1
查看>>
PHP CURL并发,多线程
查看>>
CentOS 6.5 PYPI本地源制作
查看>>
raspberry 更换阿里源
查看>>
ES 概念及动态索引结构和索引更新机制
查看>>
JavaWeb ---Filter、Servlet
查看>>
django定制自己的admin界面
查看>>
简单计划一下:
查看>>
nodejs 安装环境配置(windows)
查看>>
Eclipse 環境中的 NuttX 編譯和除錯
查看>>
INSTALLING LIGHTTPD on CentOS 6.2
查看>>
子类能否重写父类的静态方法
查看>>
JS正则表达式验证身份证号码
查看>>