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-core
和 H2 驱动 版本。
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
,允许第三方应用集成 HibernateStrategySelector
:用于解析各种策略接口的实现
要创建一个 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 项目。