Hibernate4 buildSessionFactory与 ServiceRegistry

在用Hibernate4时会发现:

 

 

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



 

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

 

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

 

[java]  view plain copy
 
  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 plain copy
 
  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().
3applySettings(configuration.getProperties());
4SessionFactory 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/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值