第 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-core 和 infinispan-client-hotrod 依赖项中。您不需要任何配置将适配器类存储为键或值。
但是,如果要使用适配器类作为 ProtoStream-annotated POJOS 中的可 marshallable 字段,您可以使用以下方法进行:
-
使用
AutoProtoSchemaBuilder注解的dependentOn元素指定CommonTypesSchema和CommonContainerTypesSchema类。
@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 {
}
@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 {
}
-
使用
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 {
}
@AutoProtoSchemaBuilder(includeClasses = { Author.class, Book.class, UUIDAdapter.class, java.math.BigInteger }, schemaFileName = "library.proto", schemaFilePath = "proto", schemaPackageName = "library")
public interface LibraryInitalizer extends SerializationContextInitializer {
}
2.1.2. ProtoStream 注解 复制链接链接已复制到粘贴板!
ProtoStream API 包含可添加到 Java 应用程序的注解,以定义 Protobuf 模式,它为对象提供结构化格式。
本主题提供有关 ProtoStream 注解的更多详情。如需更多信息,您应该参考 org.infinispan.protostream.annotations 软件包中的文档。
ProtoField
@ProtoField 定义一个 Protobuf 消息字段。
此注解是必需的,适用于字段以及 getter 和 setter 方法。类必须至少使用 @ProtoField 注解一个字段,然后才能将它作为 Protobuf。
| 参数 | 值 | 可选或必需的 | 描述 |
|---|---|---|---|
|
| 整数 | 必填 | 标签号在类内必须是唯一的。 |
|
| 类型 | 选填 | 声明字段的 Protobuf 类型。如果没有指定类型,它将从 Java 属性推断出来。
您可以使用 |
|
| 类 | 选填 | 如果属性类型是接口或抽象类,则指示实际集合类型。 |
|
| 类 | 选填 | 如果属性类型是抽象类或接口,则指示实际 Java 类型。该值必须是可立即为属性类型的 Java 类型分配。
如果您使用 |
|
| 字符串 | 选填 | 指定 Protobuf 模式的名称。 |
|
| 字符串 | 选填 | 在从缓存中读取时,请指定字段的默认值。该值必须遵循 Java 字段类型的正确语法。 |
ProtoFactory
@ProtoFactory 标记单一构造器或静态工厂方法,用于创建消息类实例。
您可以使用此注解来支持不可变消息类。所有使用 @ProtoField 注解的字段都必须包含在参数中。
-
@ProtoFactory结构或方法的字段名称和参数必须与对应的 Protobuf 消息匹配,但顺序并不重要。 -
如果您没有将
@ProtoFactory注解构造器添加到类,则该类必须具有默认的 no-argument 构造器,否则编译过程中出现错误。
AutoProtoSchemaBuilder
@AutoProtoSchemaBuilder 生成类或接口的实施,用于扩展 SerializationContextInitializer。
如果活跃,ProtoStream 处理器会在编译时以 Impl 后缀或您使用 className 参数指定的名称编译时生成实施。
includeClasses 或 basePackages 参数引用 ProtoStream 处理器应该扫描并包含在 Protobuf 模式和 marshaller 中。如果您没有设置其中一个参数,ProtoStream 处理器会扫描整个源路径,这可能会导致意外的结果,我们不建议这样做。您还可以将 excludeClasses 参数与 basePackages 参数一起使用,以排除类。
schemaFileName 和 schemaPackageName 参数在此名称下注册生成的 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 不再支持它,并可能在以后被删除。