最新の安定バージョンについては、Spring Integration 7.1.0 を使用してください! |
コーデック
Spring Integration のバージョン 4.2 は、Codec 抽象化を導入しました。コーデックは、byte[] との間でオブジェクトをエンコードおよびデコードします。Java 直列化の代替手段を提供します。1 つの利点は、通常、オブジェクトが Serializable を実装する必要がないことです。Kryo [GitHub] (英語) を使用して直列化する実装を 1 つ提供していますが、次のコンポーネントで使用する独自の実装を提供できます。
EncodingPayloadTransformerDecodingTransformerCodecMessageConverter
EncodingPayloadTransformer
このトランスフォーマーは、コーデックを使用してペイロードを byte[] にエンコードします。メッセージヘッダーには影響しません。
詳細については、Javadoc を参照してください。
DecodingTransformer
このトランスフォーマーは、コーデックを使用して byte[] をデコードします。オブジェクトのデコード先の Class (または Class に解決される式)で構成する必要があります。結果のオブジェクトが Message<?> の場合、受信ヘッダーは保持されません。
詳細については、Javadoc を参照してください。
CodecMessageConverter
特定のエンドポイント(TCP や Redis など)には、メッセージヘッダーの概念がありません。それらは MessageConverter の使用をサポートし、CodecMessageConverter は、送信のためにメッセージを byte[] との間で変換するために使用できます。
詳細については、Javadoc を参照してください。
Kryo
現在、これが Codec の唯一の実装であり、3 種類の Codec を提供します。
PojoCodec: トランスで使用MessageCodec:CodecMessageConverterで使用CompositeCodec: トランスフォーマーに使用
フレームワークは、いくつかのカスタムシリアライザーを提供します。
FileSerializerMessageHeadersSerializerMutableMessageHeadersSerializer
最初のものは、FileKryoRegistrar で初期化することにより、PojoCodec で使用できます。2 番目と 3 番目は MessageCodec で使用され、MessageKryoRegistrar で初期化されます。
CompositeCodec
CompositeCodec は、複数のコーデックを 1 つのコーデックに統合し、エンコードとデコードの処理を適切な型固有のコーデックに委譲するコーデックです。この実装は、オブジェクト型を適切なコーデックに関連付けるとともに、未登録の型に対してはフォールバックとなるデフォルトのコーデックを提供します。
実装例を以下に示します。
void encodeDecodeSample() {
Codec codec = getFullyQualifiedCodec();
//Encode and Decode a Dog Object
Dog dog = new Dog("Wolfy", 3, "woofwoof");
dog = codec.decode(
codec.encode(dog),
Dog.class);
System.out.println(dog);
//Encode and Decode a Cat Object
Cat cat = new Cat("Kitty", 2, 8);
cat = codec.decode(
codec.encode(cat),
Cat.class);
System.out.println(cat);
//Use the default code if the type being decoded and encoded is not Cat or dog.
Animal animal = new Animal("Badger", 5);
Animal animalOut = codec.decode(
codec.encode(animal),
Animal.class);
System.out.println(animalOut);
}
/**
* Create and return a {@link CompositeCodec} that associates {@code Dog} and {@code Cat}
* classes with their respective {@link PojoCodec} instances, while providing a default
* codec for {@code Animal} types.
* <p>
* @return a fully qualified {@link CompositeCodec} for {@code Dog}, {@code Cat},
* and fallback for {@code Animal}
*/
static Codec getFullyQualifiedCodec() {
Map<Class<?>, Codec> codecs = new HashMap<Class<?>, Codec>();
codecs.put(Dog.class, new PojoCodec(new KryoClassListRegistrar(Dog.class)));
codecs.put(Cat.class, new PojoCodec(new KryoClassListRegistrar(Cat.class)));
return new CompositeCodec(codecs, new PojoCodec(
new KryoClassListRegistrar(Animal.class)));
}
// Records that will be encoded and decoded in this sample
record Dog(String name, int age, String tag) {}
record Cat(String name, int age, int lives) {}
record Animal(String name, int age){} 場合によっては、単一のオブジェクト型が複数のコーデックを返すことがあります。その場合、IllegalStateException がスローされます。
このクラスは、ClassUtils.findClosestMatch を使用して、指定されたオブジェクト型に適したコーデックを選択します。複数のコーデックがオブジェクト型に一致する場合、ClassUtils.findClosestMatch は failOnTie オプションを提供します。failOnTie が false の場合、一致するコーデックのいずれかを返します。failOnTie が true で、複数のコーデックが一致する場合、IllegalStateException をスローします。CompositeCodec は failOnTie を true に設定するため、複数のコーデックが一致する場合は IllegalStateException がスローされます。 |
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 ドキュメント [GitHub] (英語) に従って、含まれるフィールドやその他の内部設定を完全に制御できます。
| カスタムシリアライザーを登録する際には、登録 ID が必要です。登録 ID は任意です。ただし、分散アプリケーション全体の各 Kryo インスタンスは同じ ID を使用する必要があるため、このケースでは ID を明示的に定義する必要があります。Kryo は小さな正の整数を推奨し、小さな ID(10 未満の値)を予約しています。Spring Integration は現在、デフォルトで 40, 41,, 42 を使用しています(前述のファイルおよびメッセージヘッダーシリアライザー用)。フレームワークの拡張性を考慮して、60 から始めることをお勧めします。前述のレジストラを設定することで、これらのフレームワークのデフォルトをオーバーライドできます。 |
カスタム Kryo シリアライザーの使用
カスタム直列化が必要な場合は、Kryo [GitHub] (英語) のドキュメントを参照してください。カスタマイズにはネイティブ 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 以外の直列化ライブラリをラップすることもできます。