1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Spring IntegrationでChainからChainを呼び出す

Posted at

開発環境

  • Java 1.8.0
  • TERASOLUNA Server Framework for Java 5.3.1.RELEASE
  • Spring core 4.3.5.RELEASE
  • Spring Integration 4.3.6.RELEASE

chainとは?

Spring Integrationでは処理と処理をchannelでつないで開発しますが、複数の処理を1つの処理としてまとめたい場合にはchainを利用すると便利です。

具体的なビーン定義は省きますが、以下のようなフロー定義した場合に

chain適用前
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:int="http://www.springframework.org/schema/integration"

  xsi:schemaLocation="http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
   ">

  <!--メッセージングゲートウェイ-->
  <int:gateway id="gateway" default-request-channel="wwwChannel"
    service-interface="com.example.WwwGateway">

  <int:filter input-channel="wwwChannel" output-channel="xxxChannel"/>

  <int:transformer input-channel="xxxChannel" output-channel="yyyChannel" />

  <int:service-activator input-channel="yyyChannel" output-channel="zzzChannel" />

chainを使うと……

chain適用後
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:int="http://www.springframework.org/schema/integration"

  xsi:schemaLocation="http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
   ">

  <!--メッセージングゲートウェイ-->
  <int:gateway id="gateway" default-request-channel="wwwChannel"
    service-interface="com.example.WwwGateway">

  <int:chain input-channel="wwwChannel" output-channel="zzzChannel">
    <int:filter/>
    <int:transformer />
    <int:service-activator />
  </chain>

と書けます!
フロー定義がchannelだらけになるのを防げる利点もあります:blush:

chainからchainを呼び出す

で、ここからが本題です。
複雑なアプリケーションを開発していると、複数の処理をまとめたchainをまとめるchainがほしくなりますよね。
chainの書き方から考えて、直感的に↓のように書きました。

chainをまとめてみた
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:int="http://www.springframework.org/schema/integration"

  xsi:schemaLocation="http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
   ">

  <!--メッセージングゲートウェイ-->
  <int:gateway id="gateway" default-request-channel="wwwChannel"
    service-interface="com.example.WwwGateway">

  <!--処理Aと処理Bをまとめるchain-->
  <int:chain input-channel="wwwChannel" output-channel="zzzChannel">
    <int:chain id="aProcess"/>
    <int:chain id="bProcess"/>
  </chain>

  <!--処理A-->
  <int:chain id="aProcess">
    <int:filter/>
    <int:transformer />
    <int:service-activator />
  </chain>

  <!--処理B-->
  <int:chain id="bProcess">
    <int:filter/>
    <int:transformer />
    <int:service-activator />
  </chain>

で、実行した結果、実行時エラー……:disappointed_relieved:
処理Aのchainと処理Bのchainに適当なinput-channelを指定したり、処理Aと処理Bをまとめるchainの中で処理Aのchainをべた書きしてもダメでした。

Gatewayを挟むことで解決

しばらく悩んでいたのですが、ふとドキュメントを読み返したら方法が書いてありました:sweat:

6.6.2 Configuring a Chainの下の方のCalling a Chain from within a Chainで、

Sometimes you need to make a nested call to another chain from within a chain and then come back and continue execution within the original chain. To accomplish this you can utilize a Messaging Gateway by including a element.

なるほど……

処理Aと処理Bをまとめるchain<int:gateway>タグを書き、request-channel属性に処理A・処理Bのinput-channelを記述したところ想定する動作になりました!
やったね!

修正後
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:int="http://www.springframework.org/schema/integration"

  xsi:schemaLocation="http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
   ">

  <!--メッセージングゲートウェイ-->
  <int:gateway id="gateway" default-request-channel="wwwChannel"
    service-interface="com.example.WwwGateway">

  <!--処理Aと処理Bをまとめるchain-->
  <int:chain input-channel="wwwChannel" output-channel="zzzChannel">
    <int:gateway request-channel="aChannel" />
    <int:gateway request-channel="bChannel" />
  </chain>

  <!--処理A-->
  <int:chain id="aProcess" input-channel="aChannel">
    <int:filter/>
    <int:transformer />
    <int:service-activator />
  </chain>

  <!--処理B-->
  <int:chain id="bProcess" input-channel="bChannel">
    <int:filter/>
    <int:transformer />
    <int:service-activator />
  </chain>

最後に

ドキュメントは読もう:joy:

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?