第 2 章 使用 ProtoStream Marshalling 自定义对象


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

Data Grid 执行 marshalling 和 unmarshalling to:

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

在 Data Grid 缓存中保存自定义对象时,您应该将基于 Protobuf 的 marshalling 与 ProtoStream marshaller 搭配使用。

2.1. ProtoStream marshalling

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

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

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

2.1.1. ProtoStream 类型

Data Grid 使用 ProtoStream 库,它可以为键和值处理以下类型,在使用原语类型时,会取消选择的等效项:

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

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

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

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

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

  • 使用 AutoProtoSchemaBuilder 注解的 dependentOn 元素指定 CommonTypesSchemaCommonContainerTypesSchema 类。
@AutoProtoSchemaBuilder(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
  • 使用 AutoProtoSchemaBuilder 注解的 includeClasses 元素指定所需的适配器类
@AutoProtoSchemaBuilder(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 软件包中的文档。

ProtoField

@ProtoField 定义一个 Protobuf 消息字段。

此注解是必需的,适用于字段以及 getter 和 setter 方法。类必须至少使用 @ProtoField 注解一个字段,然后才能将它作为 Protobuf。

Expand
参数可选或必需的描述

number

整数

必填

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

type

类型

选填

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

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

collectionImplementation

选填

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

javaType

选填

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

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

name

字符串

选填

指定 Protobuf 模式的名称。

defaultValue

字符串

选填

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

ProtoFactory

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

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

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

@AutoProtoSchemaBuilder 生成类或接口的实施,用于扩展 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,或者没有使用 AutoProtoSchemaBuilder 注解,则会出现编译时间错误。

ProtoAdapter

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

如果您使用此注解:

  • 注释类,注解类必须具有一个 @ProtoFactory 注解工厂方法,用于每个字段的 marshalled 类和注解的 accessor 方法。这些方法可以是 instance 或 static 方法,其第一个参数必须是 marshalled 类。
  • 目标 enum 中必须存在具有相同命名的 enum 值。
ProtoDoc 和 ProtoDocs

@ProtoDoc@ProtoDocs 是人类可读的文本,用于记录生成的模式的消息类型、枚举或字段。

您可以使用这些注解为 Ickle 查询配置索引。

ProtoName

@ProtoName 是一个可选注解,用于指定 Protobuf 消息或枚举类型名称,并替换 @ProtoMessage 注释。

ProtoEnumValue

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

ProtoReserved 和 ProtoReservedStatements

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

ProtoTypeId

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

注意

您不应该将此注解添加到类中,因为 Data Grid 在内部使用它,标识符可以在不注意到的情况下更改。

ProtoUnknownFieldSet

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

注意

Data Grid 不建议使用此注解,因为 Google 不再支持它,并可能在以后被删除。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2025 Red Hat