編解碼器

Spring Integration 4.2 版引入了 Codec 抽象概念。編解碼器將物件編碼和解碼為 byte[]。它們提供了 Java 序列化的替代方案。一個優點是,通常物件不需要實作 Serializable。我們提供了一個使用 Kryo 進行序列化的實作,但您可以提供自己的實作,用於以下任何元件中

  • EncodingPayloadTransformer

  • DecodingTransformer

  • CodecMessageConverter

EncodingPayloadTransformer

此轉換器使用編解碼器將 Payload 編碼為 byte[]。它不會影響訊息標頭。

請參閱 Javadoc 以取得更多資訊。

DecodingTransformer

此轉換器使用編解碼器解碼 byte[]。它需要設定要將物件解碼成的 Class(或解析為 Class 的運算式)。如果產生的物件是 Message<?>,則不會保留輸入標頭。

請參閱 Javadoc 以取得更多資訊。

CodecMessageConverter

某些端點(例如 TCP 和 Redis)沒有訊息標頭的概念。它們支援使用 MessageConverter,而 CodecMessageConverter 可用於將訊息轉換為或從 byte[] 進行傳輸。

請參閱 Javadoc 以取得更多資訊。

Kryo

目前,這是 Codec 的唯一實作,它提供了兩種 Codec

  • PojoCodec:用於轉換器中

  • MessageCodec:用於 CodecMessageConverter

框架提供了幾個自訂序列化器

  • FileSerializer

  • MessageHeadersSerializer

  • MutableMessageHeadersSerializer

第一個可以與 PojoCodec 一起使用,方法是使用 FileKryoRegistrar 初始化它。第二個和第三個與 MessageCodec 一起使用,後者使用 MessageKryoRegistrar 初始化。

自訂 Kryo

預設情況下,Kryo 將未知的 Java 類型委派給其 FieldSerializer。Kryo 也為每個原始類型以及 StringCollectionMap 註冊預設序列化器。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 介面公開了 KryoInputOutput,它們提供了對包含哪些欄位和其他內部設定的完全控制,如 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 註冊類別,這可能會使該技術在某些情況下沒有幫助。