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などで詳しい人たちに意見を聞くのがよいでしょう。