2.2. 创建序列化上下文初始化器
序列化上下文初始化器可让您在 Data Grid 中注册以下内容:
- 描述用户类型的 protobuf 模式。
- 提供序列化和解序列化功能的 Marshallers。
在高级别中,您应该执行以下操作来创建序列化上下文初始化器:
- 在您的 Java 类中添加 ProtoStream 注解。
-
使用 Data Grid 提供的 ProtoStream 处理器编译您的
SerializationContextInitializer
实现。
org.infinispan.protostream.MessageMarshaller
接口已弃用,计划在以后的 ProtoStream 版本中删除。您应该忽略显示如何使用 MessageMarshaller
的代码示例或文档,直到它被完全删除。
2.2.1. 添加 ProtoStream 处理器 复制链接链接已复制到粘贴板!
Data Grid 提供了一个 ProtoStream 处理器工件,用于在编译时处理类中的 Java 注解,以生成 Protobuf 模式、附带的 marshallers 和 SerializationContextInitializer
接口的共识实现。
流程
将
protostream-processor
添加到maven-compiler-plugin
的注解处理器配置中,到pom.xml
。Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.2.2. 在 Java 类中添加 ProtoStream 注解 复制链接链接已复制到粘贴板!
通过向 Java 类及其成员添加注解来声明 ProtoStream 元数据。然后,数据网格使用 ProtoStream 处理器从这些注解生成 Protobuf 模式和相关 marshallers。
流程
使用
@ProtoField
标注您要 marshall 的 Java 字段,可直接在字段或 getter 或 setter 方法上添加。Java 类中的任何非注解字段都是临时的。例如,您有一个带有 15 个字段的 Java 类,并注解了其中五个字段。生成的架构仅包含 5 个字段,在 Data Grid 中存储类实例时,只有五个字段才会被编译。
-
使用
@ProtoFactory
为不可变对象注解构造器。注解的构造器必须初始化标有@ProtoField
的所有字段。 -
使用
@ProtoEnumValue
注解任何 Java 枚举的成员。
以下 Author.java
和 Book.java
示例显示标有 @ProtoField
和 @ProtoFactory
的 Java 类:
Author.java
Book.java
以下 Language.java
示例显示了一个 Java enum,带有 @ProtoEnumValue
以及对应的 Protobuf 模式:
language.java
language.proto
2.2.3. 创建 ProtoStream 适配器类 复制链接链接已复制到粘贴板!
ProtoStream 提供了一个 @ProtoAdapter
注解,您可以使用它来 marshall 外部第三方 Java 对象类,您无法直接注解。
流程
创建一个
适配器
类并添加@ProtoAdapter
注释,如下例所示:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.2.4. 生成序列化上下文初始化器 复制链接链接已复制到粘贴板!
添加 ProtoStream 处理器并给 Java 类添加 @ProtoSchema
注解后,您可以将 @ProtoSchema 注解添加到接口,以便 Data Grid 生成 Protobuf 模式、附带的 marshallers 和 SerializationContextInitializer
的共识实现。
默认情况下,生成的实现名称是注解的类名称,带有 "Impl" 后缀。
流程
定义一个扩展
GeneratedSchema
或其超级接口SerializationContextInitializer
的接口。注意GeneratedSchema
接口包含访问 Protobuf 模式的方法,而SerializationContextInitializer
接口只支持注册方法。-
使用
@ProtoSchema
给接口添加注释。 -
确保
includeClasses
参数包含生成的SerializationContextInitializer
实现的所有类。 -
使用
schemaFileName
参数为生成的.proto
模式指定一个名称。 -
在
target/classes
下设置一个路径,其中使用schemaFilePath
参数生成 schema 文件。 -
使用
schemaPackageName
参数为生成的.proto
模式指定软件包名称。
以下示例显示了带有 @ProtoSchema
标注的 GeneratedSchema
接口:
后续步骤
如果您使用嵌入式缓存,Data Grid 会自动注册 SerializationContextInitializer
实现。
如果使用远程缓存,您必须将 SerializationContextInitializer
实现注册到 Data Grid Server。
2.2.5. 协议缓冲最佳实践 复制链接链接已复制到粘贴板!
协议缓冲文档提供了有关如何设计消息以及如何 发展 架构以保持向后兼容性 的最佳实践 列表。
当检测到模式被更新并拒绝更新时,数据网格可以自动执行兼容性检查。检查类型可以通过全局 序列化
配置的 schema-compatibility
属性进行配置。可用级别有:
-
UNRESTRICTED
: 不执行任何检查 -
LENIENT
: 强制执行规则的子集 -
STRICT
: 所有规则都被强制执行(默认)
下表显示了为每个级别启用的兼容性检查规则
规则 | 描述 | 级别 |
---|---|---|
没有使用保留的字段 | 比较当前和更新的定义,并在任何消息之前保留字段或 ID 作为同一消息的一部分时返回警告列表。 |
|
没有更改字段 ID | 比较当前和更新的定义,并在任何字段 ID 号已更改时返回警告列表。 |
|
没有更改字段类型 | 比较当前和更新的定义,并在任何字段类型已更改时返回警告列表。 |
|
没有删除没有保留的字段 | 比较当前和更新的定义,并在没有相应保留该字段名称或 ID 的情况下删除任何字段时返回警告列表。 |
|
没有删除保留的字段 | 比较当前和更新的定义,并在删除了任何保留字段时返回警告列表。 |
|
没有更改字段名称 | 比较当前和更新的定义,并在任何消息之前字段被重命名时返回警告列表。 |
|
2.2.6. 注册序列化上下文初始化器 复制链接链接已复制到粘贴板!
对于嵌入式缓存,Data Grid 会自动使用 java.util.ServiceLoader
在注解的 SerializationContextInitializer
实现中注册序列化上下文和 marshallers。
如果您希望,您可以禁用 SerializationContextInitializer
实现的自动注册,然后手动注册。
如果手动注册一个 SerializationContextInitializer
实现,它将禁用自动注册。然后您必须手动注册所有其他实现。
流程
为
ProtoSchema.service
注解设置false
。@ProtoSchema( includeClasses = SomeClass.class, ... service = false )
@ProtoSchema( includeClasses = SomeClass.class, ... service = false )
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
手动以编程方式或声明性注册
SerializationContextInitializer
实现,如下例所示:
声明
<serialization> <context-initializer class="org.infinispan.example.LibraryInitializerImpl"/> <context-initializer class="org.infinispan.example.another.SCIImpl"/> </serialization>
<serialization>
<context-initializer class="org.infinispan.example.LibraryInitializerImpl"/>
<context-initializer class="org.infinispan.example.another.SCIImpl"/>
</serialization>
programmatic
GlobalConfigurationBuilder builder = new GlobalConfigurationBuilder(); builder.serialization() .addContextInitializers(new LibraryInitializerImpl(), new SCIImpl());
GlobalConfigurationBuilder builder = new GlobalConfigurationBuilder();
builder.serialization()
.addContextInitializers(new LibraryInitializerImpl(), new SCIImpl());
2.2.7. 将 Protobuf 模式注册到 Data Grid 服务器 复制链接链接已复制到粘贴板!
将 Protobuf 模式注册到 Data Grid Server,以执行 Ickle 查询,或者从 application/x-protostream
转换到其他介质类型,如 application/json
。
先决条件
使用 ProtoStream 处理器生成 Protobuf 模式。
您可以在
target/<schemaFilePath>/
目录中找到生成的 Protobuf 模式。具有
CREATE
权限的用户。注意安全授权需要
CREATE
权限来添加模式。使用默认设置时,您至少需要deployer
角色。
流程
使用以下方法之一向 Data Grid 服务器添加 Protobuf 模式:
- 在任何浏览器中打开 Data Grid Console,选择 Schema 选项卡,然后选择 Add Protobuf 模式。
使用 Data Grid 命令行界面(CLI)中的
schema
命令和--upload=
参数。schema --upload=person.proto person
schema --upload=person.proto person
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 REST API 将
POST
请求的有效负载中包含 Protobuf 模式。POST/rest/v2/schemas/<schema_name>
POST/rest/v2/schemas/<schema_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用带有 Hot Rod 客户端生成的
SerializationContextInitializer
实现来注册 Protobuf 模式,如下例所示:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用
SerializationContextInitializer
实现和自定义类将 JAR 文件添加到$RHDG_HOME/server/lib
目录。当您这样做时,Data Grid 服务器在启动时注册 Protobuf 模式。但是,您必须将存档添加到每台服务器安装中,因为模式不会保存在
___protobuf_metadata
缓存中,或者在集群中自动分发。注意如果您需要 Data Grid 服务器执行任何
application/x-protostream
到application/x-java-object
转换,则必须执行此操作,在这种情况下,还必须为您的 POJO 添加任何 JAR 文件。
后续步骤
使用您的 Hot Rod 客户端注册 SerializationContextInitializer
,如下例所示:
2.2.8. 手动序列化上下文初始化器实现 复制链接链接已复制到粘贴板!
Data Grid 强烈建议您手动实施 SerializationContextInitializer
或 GeneratedSchema
接口。
可以使用 ProtobufTagMarshaller
和 RawProtobufMarshaller
注解手动实现 SerializationContextInitializer
或 GeneratedSchema
接口。
但是,手动实现需要大量开销,且容易出错。使用 protostream-processor
工件生成的实现是配置 ProtoStream marshalling 更有效且可靠的方法。