フィルター
メッセージフィルターは、メッセージヘッダー値やメッセージコンテンツ自体などの条件に基づいて、Message
を渡すかドロップするかを決定するために使用されます。メッセージフィルターはルーターに似ていますが、フィルターの入力チャネルから受信した各メッセージについて、同じメッセージがフィルターの出力チャネルに送信される場合と送信されない場合があります。ルーターとは異なり、メッセージを送信するメッセージチャネルに関する決定は行いませんが、メッセージを送信するかどうかのみを決定します。
このセクションの後半で説明するように、フィルターは破棄チャネルもサポートします。場合によっては、ブール条件に基づいて、非常に単純なルーター(または「スイッチ」)のロールを果たすことができます。 |
Spring Integration では、MessageSelector
インターフェースの実装に委譲するメッセージエンドポイントとしてメッセージフィルターを構成できます。次のように、このインターフェース自体は非常にシンプルです。
public interface MessageSelector {
boolean accept(Message<?> message);
}
MessageFilter
コンストラクターは、次の例に示すように、セレクターインスタンスを受け入れます。
MessageFilter filter = new MessageFilter(someSelector);
名前空間と SpEL を組み合わせて、ごくわずかな Java コードで強力なフィルターを構成できます。
XML を使用したフィルターの構成
<filter>
要素を使用して、メッセージ選択エンドポイントを作成できます。input-channel
および output-channel
属性に加えて、ref
属性が必要です。次の例に示すように、ref
は MessageSelector
実装を指すことができます。
<int:filter input-channel="input" ref="selector" output-channel="output"/>
<bean id="selector" class="example.MessageSelectorImpl"/>
または、method
属性を追加できます。その場合、ref
属性は任意のオブジェクトを参照できます。参照されるメソッドは、受信メッセージの Message
型またはペイロード型のいずれかを予期する場合があります。メソッドはブール値を返す必要があります。メソッドが "true" を返す場合、メッセージは出力チャネルに送信されます。次の例は、method
属性を使用するフィルターを構成する方法を示しています。
<int:filter input-channel="input" output-channel="output"
ref="exampleObject" method="someBooleanReturningMethod"/>
<bean id="exampleObject" class="example.SomeObject"/>
セレクターまたは適合された POJO メソッドが false
を返す場合、拒否されたメッセージの処理を制御する設定がいくつかあります。デフォルトでは(前の例のように構成されている場合)、拒否されたメッセージは静かにドロップされます。拒否によりエラー状態が発生する場合は、次の例に示すように、throw-exception-on-rejection
属性を true
に設定します。
<int:filter input-channel="input" ref="selector"
output-channel="output" throw-exception-on-rejection="true"/>
拒否されたメッセージを特定のチャネルにルーティングする場合は、次の例に示すように、その参照を discard-channel
として提供します。
<int:filter input-channel="input" ref="selector"
output-channel="output" discard-channel="rejectedMessages"/>
アドバイスフィルターも参照してください。
メッセージフィルターは、一般にパブリッシュ / サブスクライブチャネルと組み合わせて使用されます。多くのフィルターエンドポイントは同じチャネルにサブスクライブでき、サポートされている型(サービスアクティベーターなど)のいずれかである可能性がある次のエンドポイントにメッセージを渡すかどうかを決定します。これは、単一のポイントツーポイント入力チャネルと複数の出力チャネルを備えたメッセージルーターを使用する、より積極的なアプローチのリアクティブな代替手段を提供します。 |
カスタムフィルターの実装が他の <filter>
定義で参照されている場合は、ref
属性を使用することをお勧めします。ただし、カスタムフィルターの実装が単一の <filter>
要素にスコープされている場合は、次の例に示すように、内部 Bean 定義を提供する必要があります。
<int:filter method="someMethod" input-channel="inChannel" output-channel="outChannel">
<beans:bean class="org.foo.MyCustomFilter"/>
</filter>
同じ <filter> 構成で ref 属性と内部ハンドラー定義の両方を使用することは、あいまいな条件を作成して例外をスローするため、許可されません。 |
ref 属性が MessageFilter を継承する Bean を参照する場合(フレームワーク自体によって提供されるフィルターなど)、構成は、出力チャネルをフィルター Bean に直接注入することにより最適化されます。この場合、各 ref は個別の Bean インスタンス(または prototype -scoped Bean)に属しているか、内部 <bean/> 構成型を使用する必要があります。ただし、この最適化は、フィルター XML 定義にフィルター固有の属性を指定しない場合にのみ適用されます。誤って複数の Bean から同じメッセージハンドラーを参照すると、構成例外が発生します。 |
SpEL サポートの導入により、Spring Integration は expression
属性をフィルター要素に追加しました。次の例に示すように、単純なフィルターで Java を完全に回避するために使用できます。
<int:filter input-channel="input" expression="payload.equals('nonsense')"/>
expression 属性の値として渡された文字列は、評価コンテキストで利用可能なメッセージとともに SpEL 式として評価されます。アプリケーションコンテキストのスコープに式の結果を含める必要がある場合は、次の例に示すように、SpEL リファレンスドキュメントで定義されている #{}
表記を使用できます。
<int:filter input-channel="input"
expression="payload.matches(#{filterPatterns.nonsensePattern})"/>
式自体を動的にする必要がある場合は、「式」サブ要素を使用できます。それは、ExpressionSource
からのキーによって式を解決するための間接性のレベルを提供します。これは、直接実装できる戦略インターフェースです。または、「リソースバンドル」から式をロードし、指定された秒数後に変更を確認できる Spring Integration で利用可能なバージョンに依存できます。このすべては、基になるファイルが変更された場合に 1 分以内に式をリロードできる次の構成例で示されています。
<int:filter input-channel="input" output-channel="output">
<int:expression key="filterPatterns.example" source="myExpressions"/>
</int:filter>
<beans:bean id="myExpressions" id="myExpressions"
class="o.s.i.expression.ReloadableResourceBundleExpressionSource">
<beans:property name="basename" value="config/integration/expressions"/>
<beans:property name="cacheSeconds" value="60"/>
</beans:bean>
ExpressionSource
Bean の名前が expressionSource
の場合、<expression>
要素に `source` 属性を指定する必要はありません。ただし、前の例では、完全を期すために示しています。
次の例に示すように、"config/integration/expressions.properties" ファイル(またはリソースバンドルがロードされる一般的な方法で解決されるロケール拡張機能を備えたより具体的なバージョン)には、キー / 値のペアを含めることができます。
filterPatterns.example=payload > 100
属性またはサブ要素として expression を使用するこれらの例はすべて、トランスフォーマー、ルーター、スプリッター、サービスアクティベーター、ヘッダーエンリッチャー要素内でも適用できます。メソッド呼び出しの戻り値が解釈されるのと同じように、与えられたコンポーネント型のセマンティクスとロールは評価結果の解釈に影響を与えます。例: 式は、ルーターコンポーネントによってメッセージチャネル名として扱われる文字列を返すことができます。ただし、メッセージに対してルートオブジェクトとして式を評価し、接頭辞 "@" が付いている場合に Bean 名を解決する基本機能は、Spring Integration 内のすべてのコア EIP コンポーネントで一貫しています。 |
アノテーション付きのフィルターの構成
次の例は、アノテーションを使用してフィルターを構成する方法を示しています。
public class PetFilter {
...
@Filter (1)
public boolean dogsOnly(String input) {
...
}
}
1 | このメソッドがフィルターとして使用されることを示すアノテーション。このクラスをフィルターとして使用する場合は、指定する必要があります。 |
XML 要素によって提供されるすべての構成オプションは、@Filter
アノテーションでも使用できます。
フィルターは、XML から明示的に参照するか、クラスで @MessageEndpoint
アノテーションが定義されている場合、クラスパススキャンにより自動的に検出されます。
アノテーションを使用したエンドポイントへのアドバイスも参照してください。