`

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配置二级缓存

    SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry); ``` 通过以上步骤,你就可以成功地在Hibernate4项目中配置并使用Ehcache作为二级缓存。不过,需要注意的是,二级缓存并不能保证数据...

    Hibernate ORM 新特性之 Service(Registry).

    SessionFactory sf = configuration.buildSessionFactory(serviceRegistry); ``` 通过这种方式,Hibernate ORM引入了更灵活和模块化的架构,使得扩展和定制更加方便。内置的Services涵盖了各种功能,如配置解析、...

    java利用hibernate连接数据库

    通过Hibernate,我们可以将Java对象与数据库表进行映射,使得数据操作更加便捷和高效。 二、Hibernate环境搭建 1. 添加依赖:在Java项目中,你需要引入Hibernate的JAR包或通过Maven/Gradle等构建工具添加相关依赖。...

    java hibernate连接池源码

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); ``` 在这个过程中,Hibernate会读取配置文件并创建相应的ServiceRegistry,然后根据ServiceRegistry创建SessionFactory,...

    hibernate核心代码

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); ``` 4. **Session**: Session是与数据库交互的主要接口,它提供了 CRUD 操作。例如,保存一个实体: ```java Session ...

    Hibernate配置

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); ``` **4. Hibernate工具** 除了上述手动配置,还可以使用Hibernate的命令行工具(如`hibernatetool`)生成Java实体类和映射文件,...

    hibernate3连接sql server的例子

    **hibernate3连接sql server的例子** 在Java开发中,Hibernate是一个非常流行的对象关系映射(ORM)框架,它简化...通过这个例子,开发者可以深入理解Hibernate 3如何与SQL Server配合工作,并将其应用到实际项目中。

    hibernate 连接sqlserver2000

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); Session session = sessionFactory.openSession(); ``` 7. **CRUD操作**: 使用`Session`对象进行增删查改操作。例如,保存一个实体...

    hibernate的简单例子

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); Session session = sessionFactory.openSession(); ``` **CRUD操作** 使用Hibernate进行CRUD(Create、Read、Update、Delete)...

    hibernate环境搭建基本操作封装

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); ``` 4. **操作封装**: 建立DAO(数据访问对象)层,对增删改查进行封装。例如,以下是如何执行CRUD操作: - **保存**: `...

    hsqldb整合hibernate

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); Session session = sessionFactory.openSession(); ``` ### 6. 数据库操作 使用`Session`对象,你可以执行增删改查操作。例如,...

    Hibernate连接数据库的注册的项目

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); ``` 在理解了基本配置之后,我们还需要定义实体类,这些类将代表数据库中的表。实体类需要使用`@Entity`注解,并通过`@Table`指定...

    使用 HibernateSessionFactory 类

    2. **实体类**: 定义与数据库表对应的Java类,并使用Hibernate的注解(@Entity、@Table等)进行标注,以便ORM映射。 3. **配置对象**: 使用`Configuration`类加载配置文件,例如: ```java Configuration config ...

    使用Maven配置Hibernate5

    SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry); Session session = sessionFactory.openSession(); ``` 现在你可以通过`Session`对象进行CRUD操作了。例如,创建一个新的用户: ```...

    hibernate与proxool连接池整合demo

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); // 数据操作... ...

    hibernate安装手记

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); ``` 7. **操作数据库** 使用SessionFactory创建Session,通过Session进行CRUD操作。例如,保存一个User对象: ```java ...

    Hibernate通过配置文件自动生成表

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); ``` 然后,使用Session执行CRUD操作: ```java Session session = sessionFactory.openSession(); Transaction transaction = ...

    hibernate实现增删改查

    SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); ``` **六、增删改查操作** 1. **增加(Create)**:使用`Session`的`save()`或`saveOrUpdate()`方法可以将Java对象持久化到数据库...

Global site tag (gtag.js) - Google Analytics