編解碼器
Spring Integration 的 4.2 版本引入了 `Codec` 抽象。編解碼器(Codec)用於將物件編碼為 `byte[]` 並從 `byte[]` 解碼物件。它們提供了 Java 序列化的替代方案。一個優勢是,通常物件不需要實現 `Serializable` 介面。我們提供了一個使用 Kryo 進行序列化的實現,但您可以提供自己的實現,用於以下任何元件:
-
EncodingPayloadTransformer
-
DecodingTransformer
-
CodecMessageConverter
`EncodingPayloadTransformer`
此轉換器使用編解碼器將 payload 編碼為 `byte[]`。它不影響訊息頭。
有關更多資訊,請參閱 Javadoc。
`DecodingTransformer`
此轉換器使用編解碼器解碼 `byte[]`。需要配置物件應解碼到的 `Class`(或解析為 `Class` 的表示式)。如果結果物件是 `Message>`,則入站頭不會被保留。
有關更多資訊,請參閱 Javadoc。
`CodecMessageConverter`
某些端點(如 TCP 和 Redis)沒有訊息頭的概念。它們支援使用 `MessageConverter`,而 `CodecMessageConverter` 可以用於將訊息轉換為 `byte[]` 或從 `byte[]` 轉換回訊息進行傳輸。
有關更多資訊,請參閱 Javadoc。
Kryo
目前,這是 `Codec` 的唯一實現,它提供了兩種 `Codec`:
-
`PojoCodec`:在轉換器中使用
-
`MessageCodec`:在 `CodecMessageConverter` 中使用
框架提供了幾種自定義序列化器:
-
FileSerializer
-
MessageHeadersSerializer
-
MutableMessageHeadersSerializer
第一個可以透過使用 `FileKryoRegistrar` 初始化 `PojoCodec` 來使用。第二個和第三個與 `MessageCodec` 一起使用,`MessageCodec` 使用 `MessageKryoRegistrar` 進行初始化。
自定義 Kryo
預設情況下,Kryo 將未知 Java 型別委託給其 `FieldSerializer`。Kryo 還為每種基本型別以及 `String`、`Collection` 和 `Map` 註冊預設序列化器。`FieldSerializer` 使用反射遍歷物件圖。更有效的方法是實現一個自定義序列化器,該序列化器瞭解物件的結構並可以直接序列化選定的基本欄位。以下示例展示了這樣的序列化器:
public class AddressSerializer extends Serializer<Address> {
@Override
public void write(Kryo kryo, Output output, Address address) {
output.writeString(address.getStreet());
output.writeString(address.getCity());
output.writeString(address.getCountry());
}
@Override
public Address read(Kryo kryo, Input input, Class<Address> type) {
return new Address(input.readString(), input.readString(), input.readString());
}
}
`Serializer` 介面暴露了 `Kryo`、`Input` 和 `Output`,它們提供了對包含哪些欄位以及其他內部設定的完全控制,如 Kryo 文件中所述。
註冊自定義序列化器時,需要一個註冊 ID。註冊 ID 是任意的。但是,在我們的情況下,ID 必須明確定義,因為分散式應用程式中的每個 Kryo 例項都必須使用相同的 ID。Kryo 建議使用小的正整數,並保留一些 ID(值 < 10)。Spring Integration 當前預設使用 40、41 和 42(用於前面提到的檔案和訊息頭序列化器)。我們建議您從 60 開始,以便框架未來擴充套件。您可以透過配置前面提到的註冊器來覆蓋這些框架預設值。 |
使用自定義 Kryo 序列化器
如果您需要自定義序列化,請參閱 Kryo 文件,因為您需要使用原生 API 進行自定義。例如,請參閱 `org.springframework.integration.codec.kryo.MessageCodec` 的實現。
實現 KryoSerializable
如果您有對域物件原始碼的 `write` 訪問許可權,可以按照此處所述實現 `KryoSerializable`。在這種情況下,類本身提供序列化方法,無需進一步配置。然而,基準測試表明,這不如明確註冊自定義序列化器那樣高效。以下示例展示了一個自定義 Kryo 序列化器:
public class Address implements KryoSerializable {
@Override
public void write(Kryo kryo, Output output) {
output.writeString(this.street);
output.writeString(this.city);
output.writeString(this.country);
}
@Override
public void read(Kryo kryo, Input input) {
this.street = input.readString();
this.city = input.readString();
this.country = input.readString();
}
}
您也可以使用此技術來包裝 Kryo 以外的序列化庫。
使用 `@DefaultSerializer` 註解
Kryo 還提供了一個 `@DefaultSerializer` 註解,如此處所述。
@DefaultSerializer(SomeClassSerializer.class)
public class SomeClass {
// ...
}
如果您對域物件有 `write` 訪問許可權,這可能是指定自定義序列化器的一種更簡單的方法。請注意,這不會使用 ID 註冊類,這可能導致此技術在某些情況下不太有用。