Spring Integrationの概要

今回のブログは、Spring Framework Advent Calendar 2012の13日目の記事として投稿します。

前回のブログでSpring Integrationを話題にしたので、今回は、Spring Integrationの概要と、どのようなコーディングになるかを紹介したいと思います。ただ、独自の解釈が入っており、表現がマニュアル等と違う部分があると思いますので、ご了承ください。

主要なキーワード

まず、Spring Integrationを使用する上で主要なキーワード4つを以下に記載します。

  • Message

Spring Integrationでやりとりするデータのことです。

  • Channel

一般的な説明では、データの送信側と受信側をつなぐものになりますが、個人的には、「Messageが格納される場所」「Messageをどのように提供するか?を定義する場所」と解釈しています。「どのように提供するか?」というのは、たとえば、Point-to-Pointで提供するのか、Publishre-Subscriberで提供するか、特定のMessageを優先して先に提供するかなどを指します。

  • Endpoint

一般的な説明では、Messageを受信したり送信したりする部分になりますが、個人的には、「Channelを仲介するもの」と解釈しています。

Endpointには様々な種類が存在しますが、大きくは以下の分類になります。
・Messageの流れを制御するもの
たとえば、Messageの内容に応じてChannelを振り分けたり、条件にマッチしたMessageだけ送信したり、複数のChannelから受け取ったMessageを集約して1つのChannelに送信するものなどがあります。


データ形式を変換するもの(Transformer)
Messageを、XML形式ににしたりJSON形式にしたりすることが出来ます。
 
・Applicationコードを呼び出すもの
Applicationのコード(具体的には、SpringのBeanのメソッド)を呼び出すことができます。呼び出した後、戻り値をMessageとしてChannelに格納することもできますが、以下の図のように、処理を完結させても構いません。


  • Adapter

Channelと外部システムをつなぐものです。JMS、HTTP、Mailなど様々なAdapterが存在します。Messageが外部システムに出て行く場合はOutbound Adapter、Messageが外部システムから入ってくる場合はInbound Adapterといいます。

サンプル

次のようなアプリケーションのサンプルを考えます。

SampleAppが送信したOrder(注文)データが、外部システム(メッセージキュー)を通って最終的にOrderServiceが受信するというものです。Channelが2つと、Adapter(OutboundとInbound)が2つ、Endpoint(Applicationコードを呼び出すもの)が1つ出てきます。

以下は、SpringのBean定義ファイルです。

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xmlns:jms="http://www.springframework.org/schema/integration/jms"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/integration
    http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
    http://www.springframework.org/schema/integration/jms
    http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd">

  <context:component-scan base-package="com.genba"/>

  <!-- Channel -->
  <int:channel id="channel1"/>
  <int:channel id="channel2"/>
  <!-- ActiveMQ -->
  <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="vm://localhost"/>
  </bean>
  <!-- Outbound Adapter -->
  <jms:outbound-channel-adapter id="outboundAdapter" channel="channel1" destination-name="sampleQueue"/>
  <!-- Inbound Adapter -->
  <jms:message-driven-channel-adapter id="inboundAdapter" channel="channel2" destination-name="sampleQueue"/>
  <!-- Endpoint -->
  <int:service-activator id="saveOrder" input-channel="channel2" ref="orderService" method="saveOrder"/>

</beans>

以下は、Endpointが呼び出すApplicationのコードとなるOrderServiceクラスです。

@Component
public class OrderService {
    public void saveOrder(Order order) {
        System.out.println("OrderID: " + order.getOrderId());
        System.out.println("OrderDate: " + order.getOrderDate());
    }
}

以下は、実行用のmainメソッドです。

public class SampleApp {
	public static void main(String[] args) {
		// DIコンテナの起動
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				"classpath:app-context.xml");
		context.start();

		// channel1を取得
		MessageChannel channel1 = (MessageChannel) context.getBean("channel1");
		
		// 送信するOrderオブジェクトを生成
		Order order = new Order();
		order.setOrderId("order001");
		order.setOrderDate(new Date());
		
		// Orderオブジェクトを送信
		channel1.send(MessageBuilder.withPayload(order).build());
	}
}

Order(注文)クラスは、属性とアクセサメソッドだけのクラスなので、ソースコードは省略します。

実行すると、以下がコンソールに表示されます。

OrderID: order001
OrderDate: Thu Dec 13 11:39:33 JST 2012

Spring IntegrationとWebアプリケーション

Spring Integrationを組み込むアプリケーションとして、Webアプリケーションをイメージする方が多いと思いますが、恐らく、Spring Integrationが内部で独自のスレッドを作るはずなので、Webアプリケーションに組み込むのは危険だと思います(APサーバがスレッドを管理できないため)。Webアプリケーションに組み込む検討をする際は、コミュニティのForumなどで詳しい人たちに意見を聞くのがよいでしょう。