1前書き

このチュートリアルでは、アプリケーション統合を作成するためのSpring Integration Java DSLについて学びます。


Spring Integrationの紹介

で作成したファイル移動統合を使用し、代わりにDSLを使用します。


2依存関係

Spring Integration Java DSLはhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.integration%22%20AND%20a%3A%22spring-integration-coreの一部です。 %22[Spring Integration Core]。

だから、我々はその依存関係を追加することができます:

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-core</artifactId>
    <version>5.0.6.RELEASE</version>
</dependency>

そして、私たちのファイル移動アプリケーションに取り組むためには、https://search.maven.org/classic/#search%7Cgav%7C1%7Ca%3A%22spring-integration-file%22[Spring Integration File]も必要になります。 :

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-file</artifactId>
    <version>5.0.6.RELEASE</version>
</dependency>


3 Spring Integration Java DSL

Java DSLが登場する以前は、Spring IntegrationコンポーネントはXMLで構成されていました。

  • DSLは、完全なSpring Integrationパイプラインを純粋にJavaで簡単に作成できる、いくつかの流暢なビルダーを紹介します。 **

それでは、パイプを通過するデータを大文字にするチャネルを作成したいとしましょう。

過去に、我々はしたかもしれません:

<int:channel id="input"/>

<int:transformer input-channel="input" expression="payload.toUpperCase()"/>

そして今、我々は代わりにすることができます:

@Bean
public IntegrationFlow upcaseFlow() {
    return IntegrationFlows.from("input")
      .transform(String::toUpperCase)
      .get();
}


4ファイル移動アプリ

ファイル移動による統合を開始するには、いくつかの簡単な構成要素が必要です。


4.1. 統合フロー

必要な最初の構成要素は統合フローです。これは

__IntegrationFlows

__builderから取得できます。

IntegrationFlows.from(...)


__from

__にはいくつかの種類がありますが、このチュートリアルでは3つだけ見ていきます。


  • __MessageSource

    __s


  • __MessageChannel

    __s、


  • __String

    __s

これら3つすべてについて、まもなくお話します。


from

を呼び出した後、いくつかのカスタマイズ方法が利用可能になりました。

IntegrationFlow flow = IntegrationFlows.from(sourceDirectory())
  .filter(onlyJpgs())
  .handle(targetDirectory())
 //add more components
  .get();

最終的に、

IntegrationFlows

は常に____IntegrationFlowのインスタンスを生成します。

  • 入力を受け取り、適切な変換を実行し、結果を出力するというこのパターンは、すべてのSpring Integrationアプリ** の基本です。


4.2. 入力ソースを記述する

まず、ファイルを移動するには、統合フローのどこでファイルを探すべきかを示す必要があります。そのためには、

MessageSource:

が必要です。

@Bean
public MessageSource<File> sourceDirectory() {
 //.. create a message source
}

簡単に言うと、

MessageSource

はhttp://joshlong.com/jl/blogPost/spring

integration

adapters

gateways

and__channels.html[アプリケーションの外部にあるメッセージ]から来ることができる場所です。

具体的には、その外部ソースをSpringのメッセージング表現に適応させることができるものが必要です。そしてこの「適応」は「入力」に焦点を当てているので、これらは「入力チャネルアダプタ」と呼ばれることがよくあります。



_spring-integration-file


dependencyは、私たちのユースケースに最適な入力チャンネルアダプタを提供します:

FileReadingMessageSource:_

@Bean
public MessageSource<File> sourceDirectory() {
    FileReadingMessageSource messageSource = new FileReadingMessageSource();
    messageSource.setDirectory(new File(INPUT__DIR));
    return messageSource;
}

ここで、

__FileReadingMessageSourceは、

INPUT

DIR

で指定されたディレクトリを読み取り、そこから

MessageSource

を作成します。


__IntegrationFlows.from

__invocationで、これをソースとして指定しましょう。

IntegrationFlows.from(sourceDirectory());


4.3. 入力ソースの設定

さて、これを長寿命のアプリケーションとして考えているのなら、起動時にすでに存在しているファイルを移動するだけでなく、ファイルが入ってきたときにそれに気付くことができるでしょう。

これを容易にするために、

from

は入力ソースのさらなるカスタマイズとして追加の

configurers

を取ることもできます。

IntegrationFlows.from(sourceDirectory(), configurer -> configurer.poller(Pollers.fixedDelay(10000)));

この場合、Spring Integrationに10秒ごとにそのソース(この場合はファイルシステム)をポーリングするように指示することで、入力ソースをより回復力のあるものにすることができます。

もちろん、これは私たちのファイル入力ソースだけには当てはまりません。このポーラーを任意の

MessageSource

に追加することができます。


4.4. 入力ソースからのメッセージのフィルタリング

次に、ファイル移動アプリケーションに特定のファイルだけを移動させたいとします。拡張子が

jpg

の画像ファイルを使用します。

これには、

GenericSelector

を使用できます。

@Bean
public GenericSelector<File> onlyJpgs() {
    return new GenericSelector<File>() {

        @Override
        public boolean accept(File source) {
          return source.getName().endsWith(".jpg");
        }
    };
}

それでは、もう一度統合フローを更新しましょう。

IntegrationFlows.from(sourceDirectory())
  .filter(onlyJpgs());

あるいは、

このフィルタは非常に単純なので、代わりにラムダ

を使用して定義することもできます。

IntegrationFlows.from(sourceDirectory())
  .filter(source -> ((File) source).getName().endsWith(".jpg"));


4.5. サービスアクティベータを使ったメッセージの処理

フィルタリングされたファイルのリストができたので、それらを新しい場所に書き込む必要があります。

____Service Activatorsは、Spring Integrationでアウトプットを検討しているときに私たちが目にするものです。


spring-integration-file



FileWritingMessageHandler

サービスアクティベータを使用しましょう。

@Bean
public MessageHandler targetDirectory() {
    FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(OUTPUT__DIR));
    handler.setFileExistsMode(FileExistsMode.REPLACE);
    handler.setExpectReply(false);
    return handler;
}

ここで、

__ FileWritingMessageHandlerは、受信した各

Message

ペイロードを

OUTPUT

DIR

に書き込みます。

もう一度更新しましょう。

IntegrationFlows.from(sourceDirectory())
  .filter(onlyJpgs())
  .handle(targetDirectory());

ところで、

setExpectReply

の使い方に注目してください。 ** 統合フローは双方向である可能性があるため、この呼び出しはこの特定のパイプが一方向であることを示しています。


4.6. インテグレーションフローを有効にする

すべてのコンポーネントを追加したら、____IntegrationFlowをBeanとして登録してそれをアクティブにする必要があります。

@Bean
public IntegrationFlow fileMover() {
    return IntegrationFlows.from(sourceDirectory(), c -> c.poller(Pollers.fixedDelay(10000)))
      .filter(onlyJpgs())
      .handle(targetDirectory())
      .get();
}


__ get


メソッドは、Spring Beanとして登録する必要がある

IntegrationFlow__インスタンスを抽出します。

アプリケーションコンテキストがロードされるとすぐに、

IntegrationFlow

に含まれるすべてのコンポーネントがアクティブになります。

そして今、私たちのアプリケーションはソースディレクトリからターゲットディレクトリへファイルを移動し始めます。


5追加コンポーネント

DSLベースのファイル移動アプリケーションでは、受信チャネルアダプタ、メッセージフィルタ、およびService Activatorを作成しました。

他のいくつかの一般的なSpring Integrationコンポーネントを見て、それらをどのように使用するかを見てみましょう。


5.1. メッセージチャンネル

前述のように、

Message Channel

はフローを初期化するもう1つの方法です。

IntegrationFlows.from("anyChannel")

これを「

anyChannel

というチャネルBeanを見つけるか作成してください。」と読むことができます。次に、他のフローから

anyChannel

に送信されたデータを読み取ります。

しかし、実際にはそれよりも汎用的です。

簡単に言うと、チャネルはプロデューサをコンシューマから抽象化します。そして、それをJavaのQueueと考えることができます。

チャネルは、フロー内の任意の場所に挿入できます

たとえば、あるディレクトリから次のディレクトリに移動するときにファイルに優先順位を付けたいとしましょう。

@Bean
public PriorityChannel alphabetically() {
    return new PriorityChannel(1000, (left, right) ->
      ((File)left.getPayload()).getName().compareTo(
        ((File)right.getPayload()).getName()));
}

その後、フローの間に

channel

への呼び出しを挿入できます。

@Bean
public IntegrationFlow fileMover() {
    return IntegrationFlows.from(sourceDirectory())
      .filter(onlyJpgs())
      .channel("alphabetically")
      .handle(targetDirectory())
      .get();
}

選ぶべきチャネルがたくさんあります。** より便利なもののいくつかは、並行性、監査、または中間永続化(KafkaまたはJMSバッファを考えてください)。

また、チャンネルは

__Bridge

__sと組み合わせると強力になります。


5.2. ブリッジ

2つのチャンネルを組み合わせたい場合は、

Bridge.

を使用します。

出力ディレクトリに直接書き込むのではなく、ファイル移動アプリケーションに別のチャネルに書き込むようにさせたとしましょう。

@Bean
public IntegrationFlow fileReader() {
    return IntegrationFlows.from(sourceDirectory())
      .filter(onlyJpgs())
      .channel("holdingTank")
      .get();
}

さて、私たちは単にそれをチャンネルに書いただけなので、

そこから他のフローにブリッジすることができます

保持タンクのメッセージをポーリングして宛先に書き込むブリッジを作成します。

@Bean
public IntegrationFlow fileWriter() {
    return IntegrationFlows.from("holdingTank")
      .bridge(e -> e.poller(Pollers.fixedRate(1, TimeUnit.SECONDS, 20)))
      .handle(targetDirectory())
      .get();
}

繰り返しますが、私たちは中間チャネルに書いたので、今度は同じファイルを使って異なるレートで書き込む別のフローを追加することができます。

@Bean
public IntegrationFlow anotherFileWriter() {
    return IntegrationFlows.from("holdingTank")
      .bridge(e -> e.poller(Pollers.fixedRate(2, TimeUnit.SECONDS, 10)))
      .handle(anotherTargetDirectory())
      .get();
}

見てのとおり、個々のブリッジは異なるハンドラのためのポーリング設定を制御できます。

アプリケーションコンテキストがロードされるとすぐに、ソースディレクトリから2つのターゲットディレクトリにファイルの移動を開始する、より複雑なアプリケーションが動作します。


6. 結論

この記事では、Spring Integration Java DSLを使用してさまざまな統合パイプラインを構築するさまざまな方法について説明しました。

基本的に、前回のチュートリアルからファイル移動アプリケーションを再作成することができました。今回は純粋なJavaを使用しました。

また、チャンネルやブリッジなど、他のいくつかのコンポーネントも見てみました。

このチュートリアルで使用されている完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-integration[over on Github]から入手できます。