編解碼器

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 註冊類,這可能導致此技術在某些情況下不太有用。