原文:http://www.open-open.com/lib/view/open1356339689713.html
已经迁移到 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提供了一个统一的加载 / 初始化 / 存放 / 获取机制.
首先来看看一个整体的类图:
整个 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的实例.
最简单的做法是:
1
2
3
|
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
(关于这里的扩展的详细解释敬请期待下一篇)
现在我们有了 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.
所以, 当有了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中提供的标准服务一一解释, 我会尽量的从代码级别来解释为什么这样设计, 和如何使用.
相关推荐
总结起来,Hibernate ORM 4.0及更高版本中的Service Registry是一个重要的新特性,它提供了更高效的服务管理和访问方式,增强了系统的可扩展性和灵活性。开发者在升级到新版本时,应适应这一变化,以便更好地利用...
该hibernate jar包包含了service.ServiceRegistryBuilder
### WebSphere Service Registry and Repository (WSRR) Handbook #### 一、概述 《WebSphere Service Registry and Repository Handbook》是一本详细介绍IBM WebSphere Service Registry and Repository(WSRR)...
### Oracle Service Registry (OSR) UDDI 的安装与使用详解 #### 一、概述 Oracle Service Registry (OSR) 是一个重要的组件,用于管理、发布和服务发现等操作。它支持多种类型的部署,包括Standalone registry、...
Registry Reviver 4.0.1.18 中文破解版下载,清理修复注册表
Registry Workshop 是一款高级的注册表编辑工具,能够完全替代 ...除了RegEdit的特性外,Registry Workshop 提供许多其他功能提高注册表编辑操作效率:能够剪切,复制和粘贴注册项和键值名,还可以进行撤销和重做操作
《Registry Workshop 4.0:深入解析注册表编辑器的强大工具》 Registry Workshop 4.0 是一款备受赞誉的注册表编辑器,专为高级用户和系统管理员设计,提供了高效且安全的方式来管理和编辑Windows操作系统的注册表。...
Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException: Unable to resolve name [org.hibernate.connection.C3P0ConnectionProvider] as strategy [org.hibernate.engine.jdbc.... ...
org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider] at org.hibernate.service.internal....
WinASO Registry Optimizer 是一个 Windows 优化工具和高级注册表清理工具,它允许您以简单的鼠标单击来安全的清理及修复注册表故障。通过修复陈旧信息及调整 Windows 注册表参数,它对系统速度的提升是值得令人注意...
Hibernate 4.x引入了重大改进,首先是引入了Service Registry,以更好地管理和配置服务。4.1.7版本继续优化了这个特性,使得服务注册更加灵活,也支持更多自定义服务。此外,这个版本支持Java 7的try-with-...
8. **技术支持与更新**:尽管是免费版本,Registry Workshop通常会提供及时的技术支持和更新,以修复潜在问题并添加新特性。 总之,Registry Workshop是一款强大的注册表编辑工具,适用于需要深入管理注册表的高级...
Files contained in registry-3.1.3.jar: META-INF/MANIFEST.MF com.ice.jni.registry.RegMultiStringValue.class com.ice.jni.registry.RegBinaryValue.class com.ice.jni.registry.RegistryException.class ...
Registry Workshop 是一款高级的注册表编辑工具 能够完全替代 WIndows 系统自带的 RegEdit 注册表编辑器 除了RegEdit的特性外 Registry Workshop 提供许多其他功能提高注册表编辑操作效率:能够剪切 复制和粘贴注册...
META-INF/MANIFEST.MF com.ice.jni.registry.HexNumberFormat.class com.ice.jni.registry.NoSuchKeyException.class com.ice.jni.registry.NoSuchValueException.class com.ice.jni.registry.RegBinaryValue.class ...
讲述了如何部署registry、registry-web的部署,以及registry-web如何管理registry私库的镜像上传、下载的授权、镜像删除、用户管理
除了RegEdit的特性外,Registry Workshop 提供许多其他功能提高注册表编辑操作效率:能够剪切,复制和粘贴注册项和键值名,还可以进行撤销和重做操作;能够快速地查找和替换所需注册项,键值名和字符串;允许编辑...
3. **调用API**:使用提供的API进行读写操作,如`Registry.createKey()`, `Registry.getValue()`, `Registry.setValue()`等。 4. **错误处理**:捕获并处理可能的异常,如权限不足、注册表键不存在等。 5. **资源...
除了RegEdit的特性外,Registry Workshop 提供许多其他功能提高注册表编辑操作效率:能够剪切,复制和粘贴注册项和键值名,还可以进行撤销和重做操作;能够快速地查找和替换所需注册项,键值名和字符串;允许编辑...
远程注册表服务(Remote Registry)是Windows操作系统中的一个重要组件,主要功能是允许远程用户修改本地计算机的注册表设置。在日常的系统管理和网络维护中,这项服务对于远程诊断和修复问题,尤其是对于IT管理员和...