5.3. 服务依赖项类型


允许服务使用以下方法之一声明对其他服务的依赖:

@org.hibernate.service.spi.InjectService

服务实施类上接受单个参数并标有 @InjectService 的任何方法都被视为请求注入其他服务。

默认情况下,方法参数的类型应当是要注入的服务角色。如果参数类型与 service 角色不同,则应当使用 InjectService 的 serviceRole 属性来显式命名该角色。

默认情况下,注入的服务被视为必需,如果缺少指定的依赖服务,则启动该服务将失败。如果要注入的服务是可选的,InjectService 的 required 属性应声明为 false。默认值为 true

org.hibernate.service.spi.ServiceRegistryAwareService

第二种方法是拉取方法,其中服务实施可选的服务接口 org.hibernate.service.spi.ServiceRegistryAwareService,它声明了单一 注入服务方法

在启动过程中,Hibernate 会将 org.hibernate.service.ServiceRegistry 自身注入到实施此接口的服务中。然后,服务可以使用 ServiceRegistry 引用来查找所需的任何其他服务。

5.3.1. Service Registry

5.3.1.1. 关于 ServiceRegistry

除服务本身外,中央服务 API 是 org.hibernate.service.ServiceRegistry 接口。服务注册表的主要用途是保存、管理和提供对服务的访问。

服务注册表采用层次结构。个注册表中的服务可以依赖于并使用同一注册表中的服务以及任何父注册表。

使用 org.hibernate.service.ServiceRegistryBuilder 构建 org.hibernate.service.ServiceRegistry 实例。

使用 ServiceRegistryBuilder 创建 ServiceRegistry 的示例

ServiceRegistryBuilder registryBuilder =
    new ServiceRegistryBuilder( bootstrapServiceRegistry );
    ServiceRegistry serviceRegistry = registryBuilder.buildServiceRegistry();
Copy to Clipboard Toggle word wrap

5.3.2. 自定义服务

5.3.2.1. 关于自定义服务

旦创建了 org.hibernate.service.ServiceRegistry,则该服务本身可能会接受重新配置,但此处的不可变性意味着添加或替换服务。因此 org.hibernate.service.ServiceRegistryBuilder 提供的另一个角色是允许对从中生成的 org.hibernate.service.ServiceRegistry 中包含的服务进行调整。

有两种方法可以告知 org.hibernate.service.ServiceRegistryBuilder 相关信息。

  • 实施 org.hibernate.service.spi.BasicServiceInitiator 类,以控制服务类按需构建,并使用其 addInitiator 方法将它添加到 org.hibernate.service.ServiceRegistryBuilder 中。
  • 只需实例化服务类,并使用其 addService 方法将它添加到 org.hibernate.service.Service RegistryBuilder 中。

这两种方法都可用于扩展注册表,例如添加新的服务角色和覆盖服务,如替换服务实施。

示例:使用 ServiceRegistryBuilder 将现有服务替换为自定义服务

ServiceRegistryBuilder registryBuilder =
    new ServiceRegistryBuilder(bootstrapServiceRegistry);
registryBuilder.addService(JdbcServices.class, new MyCustomJdbcService());
ServiceRegistry serviceRegistry = registryBuilder.buildServiceRegistry();

public class MyCustomJdbcService implements JdbcServices{

   @Override
   public ConnectionProvider getConnectionProvider() {
       return null;
   }

   @Override
   public Dialect getDialect() {
       return null;
   }

   @Override
   public SqlStatementLogger getSqlStatementLogger() {
       return null;
   }

   @Override
   public SqlExceptionHelper getSqlExceptionHelper() {
       return null;
   }

   @Override
   public ExtractedDatabaseMetaData getExtractedMetaDataSupport() {
       return null;
   }

   @Override
   public LobCreator getLobCreator(LobCreationContext lobCreationContext) {
       return null;
   }

   @Override
   public ResultSetWrapper getResultSetWrapper() {
       return null;
   }
}
Copy to Clipboard Toggle word wrap

5.3.3. Boot-Strap Registry

5.3.3.1. 关于 Boot-strap Registry

boot-strap 注册表存放绝对必须可用的服务,大多数操作都必须可用。这里的主要服务是 ClassLoaderService,这是一个完美的例子。即使解析配置文件也需要访问类加载服务,如资源查找。这是通常使用的根注册表,而不是父注册表。

boot-strap 注册表的实例使用 org.hibernate.service.BootstrapServiceRegistryBuilder 类构建。

Using BootstrapServiceRegistryBuilder

示例:使用 BootstrapServiceRegistryBuilder

BootstrapServiceRegistry bootstrapServiceRegistry =
    new BootstrapServiceRegistryBuilder()
    // pass in org.hibernate.integrator.spi.Integrator instances which are not
    // auto-discovered (for whatever reason) but which should be included
    .with(anExplicitIntegrator)
    // pass in a class loader that Hibernate should use to load application classes
    .with(anExplicitClassLoaderForApplicationClasses)
    // pass in a class loader that Hibernate should use to load resources
    .with(anExplicitClassLoaderForResources)
    // see BootstrapServiceRegistryBuilder for rest of available methods
    ...
    // finally, build the bootstrap registry with all the above options
    .build();
Copy to Clipboard Toggle word wrap

5.3.3.2. BootstrapRegistry 服务

org.hibernate.service.classloading.spi.ClassLoaderService

Hibernate 需要与类加载器交互。但是,Hibernate 或任何库与类加载器交互的方式因托管应用的运行时环境而异。应用程序服务器、OSGi 容器和其他模块化类加载系统带来了非常具体的类加载要求。此服务从这种环境复杂性中提供 Hibernate 抽象。更重要的是,它以单一兼容的方式做到这一点。

在与类加载器交互方面,Hibernate 需要以下功能:

  • 定位应用程序类的功能
  • 定位集成类的功能
  • 查找资源(如属性文件和 XML 文件)的功能
  • 加载 java.util.ServiceLoader 的功能

    注意

    目前,加载应用类的功能和加载集成类的功能组合到服务的单个 负载类 功能中。这可能在以后的版本中有所改变。

org.hibernate.integrator.spi.IntegratorService

应用程序、附加组件和其他模块需要与 Hibernate 集成。以上方法需要一个组件(通常是应用)来协调各个模块的注册。此注册代表每个模块的集成商进行。

此服务侧重于发现方面。它利用 org .hibernate.service.classloading.spi.ClassLoaderService 提供的标准 java.util.ServiceLoader 功能来发现 org.hibernate.integrator.spi.Integrator 合同的实施。

集成器只需定义一个名为 /META-INF/services/org.hibernate.integrator.spi.Integrator 的文件,并使其在类路径中可用。

此文件由 java.util.ServiceLoader 机制使用。它将列出实施 org.hibernate.integrator.spi.Integrator 接口的完全限定类名称,每行一个。

5.3.4. SessionFactory Registry

虽然最佳做法是将所有 registry 类型的实例视为针对给定 机构。SessionFactory,但该组中的服务实例明确属于单个 org.hibernate.SessionFactory

差别在于需要发起它们的时间问题。通常他们需要访问 org.hibernate.SessionFactory 才能启动。这个特殊 registry 是 org.hibernate.service.spi.SessionFactoryServiceRegistry

5.3.4.1. SessionFactory 服务

org.hibernate.event.service.spi.EventListenerRegistry

描述
用于管理事件侦听器的服务。
initiator
org.hibernate.event.service.internal.EventListenerServiceInitiator
实施
org.hibernate.event.service.internal.EventListenerRegistryImpl

5.3.5. 集成器

org.hibernate.integrator.spi.Integrator 旨在提供一种简单的途径,让开发人员能够将信息集中到构建可正常工作的 SessionFactory 的过程中。org.hibernate.integrator.spi.Integrator 接口定义了两种感兴趣的方法:

  • 集成 使我们能够在构建过程中 hook
  • 解除 集成使我们可以固定在 SessionFactory 关机中。
注意

org.hibernate.integrator.spi.Integrator 中定义了第三个方法,它是一个超载的集成形式,接受 org.hibernate.metamodel.source.MetadataImplementor 而不是 org.hibernate.cfg.Configuration

除了 IntegratorService 提供的发现方法外,应用在构建 BootstrapService Registry 时可以手动注册 Integrator 实施。

5.3.5.1. 集成器用例

org.hibernate.integrator.spi.Integrator 注册事件监听程序和提供服务,请参阅 org.hibernate.integrator.spi.ServiceContributingIntegrator

示例:注册事件列表

public class MyIntegrator implements org.hibernate.integrator.spi.Integrator {

    public void integrate(
            Configuration configuration,
            SessionFactoryImplementor sessionFactory,
            SessionFactoryServiceRegistry serviceRegistry) {
        // As you might expect, an EventListenerRegistry is the thing with which event listeners are registered  It is a
        // service so we look it up using the service registry
        final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);

        // If you wish to have custom determination and handling of "duplicate" listeners, you would have to add an
        // implementation of the org.hibernate.event.service.spi.DuplicationStrategy contract like this
        eventListenerRegistry.addDuplicationStrategy(myDuplicationStrategy);

        // EventListenerRegistry defines 3 ways to register listeners:
        //     1) This form overrides any existing registrations with
        eventListenerRegistry.setListeners(EventType.AUTO_FLUSH, myCompleteSetOfListeners);
        //     2) This form adds the specified listener(s) to the beginning of the listener chain
        eventListenerRegistry.prependListeners(EventType.AUTO_FLUSH, myListenersToBeCalledFirst);
        //     3) This form adds the specified listener(s) to the end of the listener chain
        eventListenerRegistry.appendListeners(EventType.AUTO_FLUSH, myListenersToBeCalledLast);
    }
}
Copy to Clipboard Toggle word wrap

Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2026 Red Hat
返回顶部