1. 概述

在这篇文章中,我们将深入探讨 Hibernate 5.0 引入的全新机制,用于初始化和启动 SessionFactory。我们将重点介绍 原生引导(native bootstrapping)流程,这是在 Hibernate 5.0 中重新设计的核心部分。

在 Hibernate 5.0 之前,开发者通常使用 Configuration 类来引导 SessionFactory。但这种方式现在已经被标记为过时。官方推荐使用基于 ServiceRegistry 的新 API。

简单来说,构建一个 SessionFactory 的核心就是创建一个包含 Hibernate 所需服务的 ServiceRegistry 实现

2. Maven 依赖

在深入新引导流程之前,我们需要先引入 Hibernate 的核心依赖。在 Maven 项目中,只需在 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.4.24.Final</version>
</dependency>

由于 Hibernate 是 JPA 的实现,该依赖会自动引入 JPA API

我们还需要数据库的 JDBC 驱动。本文示例使用 H2 内嵌数据库:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.1.214</version>
</dependency>

你可以随时在 Maven Central 上查看最新的 hibernate-coreH2 驱动 版本。

3. 引导 API

引导(Bootstrapping)是指构建并初始化 SessionFactory 的过程。

为了完成这个目标,我们需要一个 ServiceRegistry,其中包含 Hibernate 启动和运行时所需的 Service。接着,我们可以基于这个注册中心构建一个 Metadata 对象,它代表了应用的领域模型及其数据库映射关系

下面我们将逐一深入这些核心组件。

3.1. Service

在了解 ServiceRegistry 之前,我们先来明确什么是 Service。在 Hibernate 5.0 中,Service 是一种功能接口,定义如下:

org.hibernate.service.Service

Hibernate 默认提供了大部分常用 Service 的实现,通常情况下已经足够使用。如果需要扩展或替换某些功能,我们也可以自定义自己的 Service 实现。

在下一节中,我们会看到 Hibernate 是如何通过一个轻量级容器——ServiceRegistry 来管理这些 Service 的。

3.2. ServiceRegistry

构建 SessionFactory 的第一步是创建一个 ServiceRegistry。它用于持有 Hibernate 所需的各种 Service,其底层基于 Java SPI 机制。

✅ 可以把 ServiceRegistry 理解为一个轻量级的依赖注入容器,只不过其中的“Bean”都必须是 Service 类型。

ServiceRegistry 分为两种,且具有层级结构:

3.2.1. BootstrapServiceRegistry

这是顶层注册中心,没有父级。它包含三个核心服务:

  • ClassLoaderService:用于与各种运行环境中的 ClassLoader 进行交互
  • IntegratorService:用于发现和管理 Integrator,允许第三方应用集成 Hibernate
  • StrategySelector:用于解析各种策略接口的实现

要创建一个 BootstrapServiceRegistry 实例,我们使用 BootstrapServiceRegistryBuilder 构建器,并支持类型安全的自定义配置:

BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder()
  .applyClassLoader()
  .applyIntegrator()
  .applyStrategySelector()
  .build();

3.2.2. StandardServiceRegistry

这是在 BootstrapServiceRegistry 基础上构建的注册中心,除了上面三个服务外,还包含更多 Hibernate 所需的核心服务。这些服务的初始化定义在 StandardServiceInitiators 类中。

我们使用 StandardServiceRegistryBuilder 来创建 StandardServiceRegistry 实例:

StandardServiceRegistryBuilder standardServiceRegistryBuilder =
  new StandardServiceRegistryBuilder();

💡 StandardServiceRegistryBuilder 内部会自动创建并使用一个 BootstrapServiceRegistry 实例。当然,你也可以通过构造函数传入一个已有的 BootstrapServiceRegistry

BootstrapServiceRegistry bootstrapServiceRegistry = 
  new BootstrapServiceRegistryBuilder().build();

StandardServiceRegistryBuilder standardServiceRegistryBuilder = 
  new StandardServiceRegistryBuilder(bootstrapServiceRegistry);

接着,我们可以通过 configure() 方法加载配置文件(如默认的 hibernate.cfg.xml),然后调用 build() 获取 StandardServiceRegistry 实例:

StandardServiceRegistry standardServiceRegistry = standardServiceRegistryBuilder
  .configure()
  .build();

3.3. Metadata

有了 ServiceRegistry,我们就可以构建 Metadata 对象了。它用于表示应用的领域模型及其与数据库的映射关系。

这一步通过 MetadataSources 类来完成:

MetadataSources metadataSources = new MetadataSources(standardServiceRegistry);
metadataSources.addAnnotatedClass();  // 添加注解类
metadataSources.addResource();        // 添加 XML 映射文件

随后,我们构建出 Metadata 实例:

Metadata metadata = metadataSources.buildMetadata();

3.4. SessionFactory

最后一步,就是从 Metadata 构建出 SessionFactory

SessionFactory sessionFactory = metadata.buildSessionFactory();

现在我们可以打开 Session,进行实体的持久化和查询操作:

Session session = sessionFactory.openSession();
Movie movie = new Movie(100L);
session.persist(movie);
session.createQuery("FROM Movie").list();

4. 总结

本文我们梳理了构建 SessionFactory 的完整流程。虽然看起来步骤不少,但其实可以总结为三个核心环节:

✅ 创建 StandardServiceRegistry
✅ 构建 Metadata
✅ 构造 SessionFactory

完整代码示例可参考 GitHub 项目


原始标题:Hibernate 5 Boostrapping API