第 2 章 使用 ProtoStream 实现自定义对象


Marshalling 是一个将 Java 对象转换为可在网络传输或存储到磁盘的二进制格式的进程。反向进程 unmarshalling 将数据从二进制格式转换回 Java 对象。

Data Grid 执行 marshalling 和 unmarshalling to:

  • 将数据发送到集群中的其他 Data Grid 节点。
  • 将数据存储在持久缓存存储中。
  • 在客户端和远程缓存之间传输对象。
  • 将对象存储在 JVM 堆之外的原生内存中。
  • 当缓存编码不是 application/x-java-object 时,将对象存储在 JVM 堆内存中。

在 Data Grid 缓存中存储自定义对象时,您应该使用带有 ProtoStream marshaller 的基于 Protobuf 的 marshalling。

2.1. ProtoStream marshalling

Data Grid 提供 ProtoStream API,以便您可以将所有 Java 对象作为协议缓冲器(Protobuf)进行 marshall。

ProtoStream 原生支持许多不同的 Java 数据类型,这意味着您不需要为这些类型配置 ProtoStream marshalling。对于自定义或用户类型,您需要提供一些信息,以便数据网格可以将这些对象划分到缓存中。

SerializationContext
包含 Protobuf 类型定义的存储库,从 Protobuf 模式(.proto 文件)和附带的 marshallers 加载。
SerializationContextInitializer
初始化 SerializationContext 的接口。

2.1.1. ProtoStream 类型

Data Grid 使用了一个 ProtoStream 库,它可以针对键和值处理以下类型,并在原语类型中处理未附带的等效类型:

  • byte[]
  • byte
  • 字符串
  • 整数
  • Long
  • å�Œ
  • 浮点值
  • 布尔值
  • short
  • 字符
  • java.util.Date
  • java.time.Instant
其他类型的集合

ProtoStream 库包括多个用于常见 Java 类型的适配器类,例如:

  • java.math.BigDecimal
  • java.math.BigInteger
  • java.util.UUID
  • java.util.BitSet

Data Grid 为 protostream-types 工件中的一些通用 JDK 类提供所有适配器类,它们包含在 infinispan-coreinfinispan-client-hotrod 依赖项中。您不需要任何配置将适配器类存储为键或值。

但是,如果要使用适配器类作为 ProtoStream-annotated POJO 中的 marshallable 字段,您可以使用以下方法这样做:

  • 使用 ProtoSchema 注解的 dependentOn 元素指定 CommonTypesSchemaCommonContainerTypesSchema 类。
@ProtoSchema(dependsOn = {org.infinispan.protostream.types.java.CommonTypes, org.infinispan.protostream.types.java.CommonContainerTypes}, schemaFileName = "library.proto", schemaFilePath = "proto", schemaPackageName = "example")
public interface LibraryInitalizer extends SerializationContextInitializer {
}
Copy to Clipboard Toggle word wrap
  • 使用 ProtoSchema 注解的 includeClasses 元素指定所需的适配器类
@ProtoSchema(includeClasses = { Author.class, Book.class, UUIDAdapter.class, java.math.BigInteger }, schemaFileName = "library.proto", schemaFilePath = "proto", schemaPackageName = "library")
public interface LibraryInitalizer extends SerializationContextInitializer {

}
Copy to Clipboard Toggle word wrap

2.1.2. ProtoStream 注解

ProtoStream API 包含您可以添加到 Java 应用程序的注解来定义 Protobuf 模式,后者为对象提供结构化格式。

本主题提供有关 ProtoStream 注解的额外详情。您应该参考 org.infinispan.protostream.annotations 软件包中的文档来获取完整的信息。

Proto

@proto 定义协议缓冲消息,无需使用 @Proto Field 注释给所有字段标注。

  • 使用此注解从带有公共字段的记录或类快速生成消息。
  • 字段必须是公共的,它们将根据声明顺序分配递增数字。
  • 可以使用 ProtoField 注解覆盖字段的自动默认值。
警告

使用自动 Protobuf 字段编号只适用于快速原型。对于生产环境,您应该遵循 协议缓冲最佳实践,以确保未来/反馈与您的模式兼容。

ProtoField

@ProtoField 定义 Protobuf message 字段。

此注解适用于字段以及 getter 和 setter 方法。除非使用的是 @Proto 注释,否则类必须至少有一个字段标上 @ProtoField,然后 Data Grid 可以将其 marshall 作为 Protobuf。

Expand
参数value可选或必需的描述

number

整数

必填

标签号在类内必须是唯一的。

type

类型

选填

声明字段的 Protobuf 类型。如果没有指定类型,则会从 Java 属性中推断出它。

您可以使用 @ProtoField (type) 元素来更改 Protobuf 类型,类似于将 Java int 更改为 fixed32。Java 属性的任何不兼容的声明都会导致编译器错误。

collectionImplementation

选填

如果属性 type 是接口或抽象类,则指示实际集合类型。

javaType

选填

如果属性 type 是抽象类或接口,则表示实际的 Java 类型。该值必须为属性类型分配可即时的 Java 类型。

如果使用 javaType 参数声明类型,则所有用户代码都必须遵循该类型。如果条目为 unmarshalled,则为该条目生成的 marshaller 使用该实现。如果本地客户端使用不同于声明的实现,则会导致 ClassCastExceptions。

name

字符串

选填

指定 Protobuf 模式的名称。

defaultValue

字符串

选填

如果字段在从缓存中读取时不可用,则指定字段的默认值。该值必须遵循 Java 字段类型的正确语法。

ProtoFactory

@ProtoFactory 标记用于创建消息类实例的单个构造器或静态工厂方法。

您可以使用此注解来支持不可变消息类。使用 @ProtoField 注解的所有字段都必须包含在参数中。

  • @ProtoFactory 结构或方法的字段名称和参数必须与对应的 Protobuf 消息匹配,但顺序不重要。
  • 如果您没有将 @ProtoFactory 注解的构造器添加到类,则该类必须具有默认的 no-argument 结构器,否则编译过程中发生错误。
ProtoSchema

@ProtoSchema 生成扩展 SerializationContextInitializer 的类或接口的实施。

如果激活,ProtoStream 处理器会在编译时在带有 Impl 后缀或您使用 className 参数指定的名称相同的软件包中生成实现。

includeClassesbasePackages 参数引用 ProtoStream 处理器应扫描并包含在 Protobuf 模式和 marshaller 中的类。如果您没有设置这些参数,ProtoStream 处理器会扫描整个源路径,这可能会导致意外的结果,我们不建议这样做。您还可以使用 excludeClasses 参数和 basePackages 参数来排除类。

schemaFileNameschemaPackageName 参数在此名称下注册生成的 Protobuf 模式。如果没有设置这些参数,则注释的简单类名称将与未命名或默认软件包一起使用。模式名称必须以 .proto 文件扩展名结尾。您还可以使用 marshallersOnly 来只生成 marshallers,并阻止 Protobuf 模式生成。

ProtoStream 进程自动生成 META-INF/services 服务元数据文件,您可以使用这些文件以便 Data Grid 服务器自动获取 JAR 来注册 Protobuf 模式。

dependentOn 参数列出了实施 SerializedContextInitializer 的注解类,以首先执行。如果类没有实现 SerializedContextInitializer,或使用 ProtoSchema 注解,则会出现编译时间错误。

ProtoAdapter

@ProtoAdapter 是无法直接注解的类或枚举的 marshalling adapter。

如果您将此注解用于:

  • 注解的类必须具有一个 @ProtoFactory 注解的 marshalled 类并为每个字段标注的 accessor 方法。这些方法可以是 instance 或 static 方法,其第一个参数必须是 marshalled 类。
  • Enums,目标枚举中必须存在相同的命名 enum 值。
ProtoName

@ProtoName 是一个可选注释,用于指定 Protobuf 消息或 enum 类型名称。它可用于类、记录和枚举。

ProtoEnumValue

@ProtoEnumValue 定义 Protobuf enum 值。您只能将此注解应用到 Java enum 的成员。

ProtoReserved 和 ProtoReservedStatements

@ProtoReserved@ProtoReservedStatements保留的 语句添加到生成的消息或枚举定义中,以防止以后使用数字、范围和名称。

ProtoTypeId

@ProtoTypeId (可选)为 Protobuf 消息或 enum 类型指定全局唯一的数字类型标识符。

注意

您不应该将此注解添加到类,因为 Data Grid 在内部使用,标识符可能会在不通知的情况下改变。

ProtoUnknownFieldSet

@ProtoUnknownFieldSet (可选)表示字段或类型为 {@link org.infinispan.protostream.UnknownFieldSet} 的 JavaBean 属性,它存储了任何未知字段。

注意

Data Grid 不推荐使用这个注解,因为它不再被 Google 支持,并可能在以后被删除。

其他注解

Data Grid 将类、字段和方法上的任何其他注解复制为生成的 Protobuf 模式中的注释。这包括索引注释,如 @Indexed@Basic

Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2026 Red Hat
返回顶部