Hibernate ORM 新特性之 Service(Registry)(一)

2014-11-24 10:55:46 · 作者: · 浏览: 0
Service Registry
已经迁移到 Hibernate Core 4.0 的用户(非JPA)可能已经注意到,以前大家熟知的构造 SessionFactory 的方法已经不推荐使用了:
Configuration configuration = new Configuration();
SessionFactory sf = configuration.buildSessionFactory();
在 Hibernate ORM 4 里面推荐的方式是 org.hibernate.cfg.Configuration#buildSessionFactory(ServiceRegistry serviceRegistry), 需要先构造一个 ServiceRegistry 对象。
那么, 神马是 ServiceRegistry
顾名思义, ServiceRegistry 是 Service 的注册表, 它为Service提供了一个统一的加载 / 初始化 / 存放 / 获取机制.
首先来看看一个整体的类图:
整个 ServiceRegistry 结构和我们大家了解的 Classloader 的代理结构类似, 只不过和 Classloader 的首先代理给父节点,父节点找不到再从本级的 Classloader 中查找的策略不同,ServiceRegistry 是先从本级节点查找,找不到再去父亲中查找。
可以看到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, 详细介绍请参考:
Building ServiceRegistry
在本文的开头即说过, 现在标准的构造一个SessionFactory的做法是传递一个ServiceRegistry实例给Configuration#buildSessionFactory方法, 那么, 这里就需要我们首先创建一个 ServiceRegistry的实例.
最简单的做法是:
StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
SessionFactory sf = configuration.buildSessionFactory(serviceRegistry);
让我们来继续分析这里面究竟发生了什么.
如上文所介绍的, ServiceRegistry是一个代理结构, 那么, 实际上是需要分别创建 BootstrapServiceRegistry, ServiceRegistry 和 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 www.2cto.com
(关于这里的扩展的详细解释敬请期待下一篇)
现在我们有了 BootstrapServiceRegistryBuilder 和 ServiceRegistryBuilder , 那么很自然的, 会想到是不是也有一个 SessionFactoryServiceRegistryBuilder 呢
很遗憾, 没有!
是的, 不过我们提供了 org.hibernate.service.spi.SessionFactoryServiceRegistryFactory, 它是一个位于 ServiceRegistry 中的标准service.
这主要是因为它的全部工作就是创建一个没啥意思的 org.hibernate.service.internal.SessionFactoryServiceRegistryImpl 实例, 也没啥可扩展的地方, 所以自然也就不需要一个builder了.