編解碼器
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 也為每個原始類型以及 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 註冊類別,這可能會使該技術在某些情況下沒有幫助。