`

Hibernate4 buildSessionFactory与 ServiceRegistry

 
阅读更多

在用Hibernate4时会发现:

 

 

[java] view plaincopy
 
  1. SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();  



 

buildSessionFactory()废弃,相信很多人会觉得为什么废弃这方法,查了网上的资料,综合如下:

 

Hibernate给了个ServiceRegistry,然后拿到sessionFactory是通过:

 

[java] view plaincopy
 
  1. @BeforeClass  
  2. public static void beforeClass() {  
  3.         Configuration configuration = new Configuration();  
  4.         //new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);  
  5.         //sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();  
  6.         ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();  
  7.         SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);  



像网友说的具有注册表存储库功能,功能更多了,上面的方法废弃,其实是hibernate想你用这个类,因为他们写了个更好的东西出来。原来是这样。其实里面的源码还是:

 

 

[java] view plaincopy
 
  1. package cn.framework.dao.util;  
  2. import org.hibernate.HibernateException;  
  3. import org.hibernate.SessionFactory;  
  4. import org.hibernate.cfg.Configuration;  
  5. import org.hibernate.service.ServiceRegistry;  
  6. import org.hibernate.service.ServiceRegistryBuilder;  
  7. public class HibernateUtil {  
  8.    
  9.  public static SessionFactory sessionfactory = null;  
  10.  static {  
  11.   try {  
  12.    // 通过hibernate.cfg.xml 产生一个SessionFactory  还是和原来的方法一样的。。  
  13.    sessionfactory = new Configuration().configure().buildSessionFactory();  
  14.   } catch (Throwable ce) {  
  15.    ce.printStackTrace();  
  16.   }  
  17.  }  

 

 

还是用到我们上面所谓的废弃的方法。

以上内容转自:http://blog.csdn.net/iaiti/article/details/9211905

 

已经迁移到 Hibernate Core 4.0 的用户(非JPA)可能已经注意到,以前大家熟知的构造 SessionFactory 的方法已经不推荐使用了:

1
2
Configuration configuration = new Configuration();
SessionFactory sf = configuration.buildSessionFactory();

 

在 Hibernate ORM 4 里面推荐的方式是 org.hibernate.cfg.Configuration#buildSessionFactory(ServiceRegistry serviceRegistry), 需要先构造一个 ServiceRegistry 对象。

那么, 神马是 ServiceRegistry?

顾名思义, ServiceRegistry 是 Service 的注册表, 它为Service提供了一个统一的加载 / 初始化 / 存放 / 获取机制.

首先来看看一个整体的类图:

Hibernate 4.0 新特性之 Service(Registry)

整个 ServiceRegistry 结构和我们大家了解的 Classloader 的代理结构类似, 只不过和 Classloader 的首先代理给父节点,父节点找不到再从本级的 Classloader 中查找的策略不同,ServiceRegistry 是先从本级节点查找,找不到再去父亲中查找。

Hibernate 4.0 新特性之 Service(Registry)

可以看到hibernate里面的 ServiceRegistry实际上是由三层(范围)组成的:

  • BootstrapServiceRegistry

主要提供 Classloading 和 Service loading 服务, 供全局使用.

  • ServiceRegistry

标准的ServiceRegistry, 同样服务于全局, 在初始化这个Registry中的服务的时候,可能需要使用到BootstrapServiceRegistry中的服务.

  • SessionFactoryServiceRegistry

SessionFactory相关联(一对一的关系), 这里面的Services在初始化的时候需要访问SessionFactory.

所以, BootstrapServiceRegistry 中主要包括全局都要使用的基础服务, 而 ServiceRegistry 主要包括在BootstrapServiceRegistry 之上的, 和Hibernate 相关的服务, 例如配置文件解析, JDBC, JNDI 等.

而, SessionFactoryServiceRegistry 则是和sessionfactory相关的了, 包括2LC的region factory, event listener等.

这里面的层级关系, 对于 service registry的client来说是完全透明的, 你可以直接调用getService 去获取你需要的service, 而不用去关心你在哪个层级上, 如同 classloader.

Service

那么,什么是 Service ? 简单的来说,Service 就是一个功能,它由一个接口(Service Role)和一个实现类组成.

Service 在Hibernate里面并不是一个新的概念,在以前的版本里面,我们已经有了这些东西,而这次,是通过把这些服务的提供者(类),给抽取成一个个的Service,从而可以用统一的方式进行访问/加载/初始化等.

下图列出了所有的Hibernate中内置的Services, 详细介绍请参考:

Hibernate 4.0 新特性之 Service(Registry)

Building ServiceRegistry

在本文的开头即说过, 现在标准的构造一个SessionFactory的做法是传递一个ServiceRegistry实例给Configuration#buildSessionFactory方法, 那么, 这里就需要我们首先创建一个 ServiceRegistry的实例.

最简单的做法是:

1
2
3
StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
SessionFactory sf = configuration.buildSessionFactory(serviceRegistry);

 

让我们来继续分析这里面究竟发生了什么.

如上文所介绍的, ServiceRegistry是一个代理结构, 那么, 实际上是需要分别创建 BootstrapServiceRegistryServiceRegistry和 SessionFactoryServiceRegistry.

BootstrapServiceRegistry

org.hibernate.service.ServiceRegistryBuilder 有两个构造函数, 一个是接受一个 BootstrapServiceRegistry实例作为参数, 另外一个是无参的, 在内部自己构造一个 org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl的实例.

如同上面所讲的, 事实上我们是先build了一个 BootstrapServiceRegistry 的.

而Hibernate也如你所愿的提供了 org.hibernate.boot.registry.BootstrapServiceRegistryBuilder.

通过这个builder类, 我们可以通过调用如下的方法来对一些基础服务进行扩展:

  • with(Integrator integrator)
  • with(ClassLoader classLoader)
  • withStrategySelector

(关于这里的扩展的详细解释敬请期待下一篇)

现在我们有了 BootstrapServiceRegistryBuilder 和 ServiceRegistryBuilder , 那么很自然的, 会想到是不是也有一个SessionFactoryServiceRegistryBuilder 呢?

很遗憾, 没有!

是的, 不过我们提供了 org.hibernate.service.spi.SessionFactoryServiceRegistryFactory, 它是一个位于 ServiceRegistry 中的标准service.

这主要是因为它的全部工作就是创建一个没啥意思的 org.hibernate.service.internal.SessionFactoryServiceRegistryImpl 实例, 也没啥可扩展的地方, 所以自然也就不需要一个builder了.

那么, 如果你非得要替换到这个默认的实现, 或者, 更进一步, 例如你想要替换掉某一个Service的标准实现, 异或, 你想把自己写的service也添加到service registry当中呢?

更进一步来看看Service

首先, BootstrapServiceRegistry中所提供的service是固定的, 无法增减, 除非你提供一个自己的org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl 实现类, 但是并不推荐.

org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl#locateServiceBinding 方法中我们可以看到BootStrapServiceRegistry所提供的标准服务.

1
2
3
4
5
6
7
8
9
10
11
12
13
public <r service="" extends=""> ServiceBinding<r> locateServiceBinding(Class<r> serviceRole) {
    if ( ClassLoaderService.class.equals( serviceRole ) ) {
        return (ServiceBinding<r>) classLoaderServiceBinding;
    }
    else if ( StrategySelector.class.equals( serviceRole) ) {
        return (ServiceBinding<r>) strategySelectorBinding;
    }
    else if ( IntegratorService.class.equals( serviceRole ) ) {
        return (ServiceBinding<r>) integratorServiceBinding;
    }
 
    return null;
}</r></r></r></r></r></r>

 

推荐的扩展位置是 ServiceRegistry, 在这里, 你可以增加你自定义的service, 替换标准的service实现等等.

ServiceRegistry 中所提供的标准服务是定义在 org.hibernate.service.StandardServiceInitiators 当中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class StandardServiceInitiators {
    public static List<standardserviceinitiator> LIST = buildStandardServiceInitiatorList();
 
    private static List<standardserviceinitiator> buildStandardServiceInitiatorList() {
        final List<standardserviceinitiator> serviceInitiators = new ArrayList<standardserviceinitiator>();
 
        serviceInitiators.add( ConfigurationServiceInitiator.INSTANCE );
        serviceInitiators.add( ImportSqlCommandExtractorInitiator.INSTANCE );
 
        serviceInitiators.add( JndiServiceInitiator.INSTANCE );
        serviceInitiators.add( JmxServiceInitiator.INSTANCE );
 
        serviceInitiators.add( PersisterClassResolverInitiator.INSTANCE );
        serviceInitiators.add( PersisterFactoryInitiator.INSTANCE );
 
        serviceInitiators.add( ConnectionProviderInitiator.INSTANCE );
        serviceInitiators.add( MultiTenantConnectionProviderInitiator.INSTANCE );
        serviceInitiators.add( DialectResolverInitiator.INSTANCE );
        serviceInitiators.add( DialectFactoryInitiator.INSTANCE );
        serviceInitiators.add( BatchBuilderInitiator.INSTANCE );
        serviceInitiators.add( JdbcEnvironmentInitiator.INSTANCE );
        serviceInitiators.add( JdbcServicesInitiator.INSTANCE );
        serviceInitiators.add( RefCursorSupportInitiator.INSTANCE );
 
        serviceInitiators.add( SchemaManagementToolInitiator.INSTANCE );
 
        serviceInitiators.add( MutableIdentifierGeneratorFactoryInitiator.INSTANCE);
 
        serviceInitiators.add( JtaPlatformInitiator.INSTANCE );
        serviceInitiators.add( TransactionFactoryInitiator.INSTANCE );
 
        serviceInitiators.add( SessionFactoryServiceRegistryFactoryInitiator.INSTANCE );
 
 
        return Collections.unmodifiableList( serviceInitiators );
    }
}</standardserviceinitiator></standardserviceinitiator></standardserviceinitiator></standardserviceinitiator>

 

可以看到, 每一个标准服务都被封装成了 StandardServiceInitiator, 那么什么是 ServiceInitiator 呢?

ServiceInitiator

1
org.hibernate.service.spi.ServiceInitiator

定义了一个 Service 的加载器, 这个接口里面只有一个方法

1
2
3
4
5
6
/**
 * Obtains the service role initiated by this initiator.  Should be unique within a registry
 *
 * @return The service role.
 */
public Class<r> getServiceInitiated();</r>

 

org.hibernate.service.StandardServiceInitiator 继承了 org.hibernate.service.spi.ServiceInitiator 并提供了另外一个方法:

1
2
3
4
5
6
7
8
9
/**
 * Initiates the managed service.
 *
 * @param configurationValues The configuration values in effect
 * @param registry The service registry.  Can be used to locate services needed to fulfill initiation.
 *
 * @return The initiated service.
 */
public R initiateService(Map configurationValues, ServiceRegistryImplementor registry);

 

认同下图所示, ServiceInitiator定义了一个Service的接口 以及如何初始化这个service.

Hibernate 4.0 新特性之 Service(Registry)

所以, 当有了ServiceInitiator之后, 可以通过调用org.hibernate.boot.registry.StandardServiceRegistryBuilder 的方法添加到注册表中:

  • addInitiator(StandardServiceInitiator initiator)
  • addService(final Class serviceRole, final Service service)

hibernate在初始化这些service的时候, 会先初始化内置的, 所以, 如果你想要替换以后的标准service的话, 只需要原样调用上面两个方法之一就行了.

Hibernate 还提供了一些接口来供Service的创建者来使用(具体如何使用请参考javadoc,在此就不重复了):

  • org.hibernate.service.spi.Configurable
  • org.hibernate.service.spi.Manageable
  • org.hibernate.service.spi.ServiceRegistryAwareService
  • org.hibernate.service.spi.InjectService
  • org.hibernate.service.spi.Startable
  • org.hibernate.service.spi.Stoppable
  • org.hibernate.service.spi.Wrapped

至此, 已经把ServiceRegistry中的大部分内容介绍完了, 希望大家对此有个感性的认识. 在以后的blog中, 我会按照从bootstrap, standard, sessionfactory的顺序把各个service registry中提供的标准服务一一解释, 我会尽量的从代码级别来解释为什么这样设计, 和如何使用.

以上内容转自:http://www.open-open.com/lib/view/open1356339689713.html

 

How To Create Session Factory in Hibernate 4

There are many APIs deprecated in the hibernate core framework. One of the frustrating point at this time is, hibernate official documentation is not providing the clear instructions on how to use the new API and it stats that the documentation is in complete. Also each incremental version gets changes on some of the important API. One such thing is the new API for creating the session factory in Hibernate 4.3.0 on wards. In our earlier versions we have created the session factory as below:

1 SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

The method buildSessionFactory is deprecated from the hibernate 4 release and it is replaced with the new API. If you are using the hibernate 4.3.0 and above, your code has to be:

1 Configuration configuration = new Configuration().configure();
2 StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().
3 applySettings(configuration.getProperties());
4 SessionFactory factory = configuration.buildSessionFactory(builder.build());

Class ServiceRegistryBuilder is  replaced by StandardServiceRegistryBuilder from 4.3.0. It looks like there will be lot of changes in the 5.0 release. Still there is not much clarity on the deprecated APIs and the suitable alternatives to use. Every incremental release comes up with more deprecated API, they are in way of fine tuning the core framework for the release 5.0.

The above content is from: http://www.javabeat.net/session-factory-hibernate-4/

 

分享到:
评论

相关推荐

    HIbernate4.3.6整合c3p0所需jar

    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1843) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928) at test.UserTest01.save(UserTest01....

    Hibernate3使用经验

    ---------------Hibernate3.0 配置-------------- 1.Hibernate中配置参数 /** * 注意:HQL中使用参数的方法: ...SessionFactory sf = config.buildSessionFactory(); Session session = sf.openSession();

    hibernate操作数据库笔记

    用Configuration对象获取SessionFactory和Session对象:SessionFactory sf = Configuration对象.buildSessionFactory();Session session = SessionFactory对象.openSession(); 注:由于SessionFactory是重量级对象,很...

    Hibernate1

    4.创建hibernate配置文件(文件名为hibernate.cfg.xml,一般我们将其放在根目录下面) &lt;!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" ...

    J2EE利用Hibernate采用B/S架构网页设计

    import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.cfg.Configuration; /** * Configures and provides access to Hibernate sessions, tied to the * current ...

    hibernate精华教程

    4)调用hibernate API。 a)使用Configuration对象的buildSessionFactory()方法创建SessionFactory对象。 b)使用SessionFactory对象openSession()方法创建Session对象。 c)使用Session的相应方法来操作数据库,将...

    mysql+jdbc+jsp+Hibernate3.2+tomcattomcat5.028成功测试

    tomcat中配jdbc就不用说了, &lt;br&gt; &lt;br&gt;4. Event.java 文件 &lt;br&gt;package events; &lt;br&gt;import java.util.Date; &lt;br&gt;public class Event { private Long id; &lt;br&gt; private String title;...

    hibernate2

    Hibernate Annotation简单应用 接着上次的程序我们将其改为Annotation版本的 既然用Annotation那就要将其对应的包导入到工程 ... .buildSessionFactory(); 这时,我们就可以运行这个测试类了。

    Hibernate的JNDI绑定分析

    Hibernate的JNDI名称绑定是在net.sf.hibernate.impl.SessionFactoryObjectFactory... SessionFactory sf = conf.buildSessionFactory(); 首先是new Configuration()创建一个Configuration,在这个构造器里面进行

    三大框架原理

    3.通过config.buildSessionFactory();//创建SessionFactory 4.sessionFactory.openSession();//打开Sesssion 5.session.beginTransaction();//创建事务Transation 6.persistent operate持久化操作 7.session....

    Hibernate5的Query接口浅析

    Configuration cfg=new Configuration().configure("hibernate.cfg.xml"); SessionFactory sf=cfg.buildSessionFactory(); Session session=sf.getCurrentSession(); Transaction tx=session.beginTransaction();

    SSH的jar包.rar

    3.通过config.buildSessionFactory();//创建SessionFactory 4.sessionFactory.openSession();//打开Sesssion 5.session.beginTransaction();//创建事务Transation 6.persistent operate持久化操作 7.session....

    Hibernate 主清单文件配制的详细介绍

    Hibernate 主清单文件配制的详细介绍 1 Hiernate 清单配制文件 ...private static SessionFactory factory = new Configuration().configure().buildSessionFactory(); /** * 获得线程绑定的session * @return

    ACCP8.0北大青鸟SSH10章上机

    Configuration configuration = new ...或者通过MyEclipse的Hibernate工具自动生成的HibernateSessionFactory.getSession()方法来获取Session,调用HibernateSessionFactory. closeSession()方法来关闭session。

    客户关系管理系统框架搭建(二)

    SessionFactory sf=config.buildSessionFactory(); Session s=sf.openSession(); Transaction tx=s.beginTransaction(); SysUserGroup sysUserGroup=new SysUserGroup(); ...

    中小公司人事管理系统

    sf=cfg.buildSessionFactory(); } //得到一个Session public static Session getsession()throws Exception{ s=sessionThread.get(); try{ if(s==null){//如果当前的session线程中没有session对象的情况...

    nhibernate架构分析(uml图)

     SessionFactory由Configuration.BuildSessionFactory创建,这个对象一般使用Singleton模式。 Session用于将对象持久化,支持数据库事务,另外Session还提供了强大的数据加载功能。 Session由SessionFactory创建...

Global site tag (gtag.js) - Google Analytics