Spring Integration を使った標準出力

Spring Integration は ESB Mule と同様のオープンソース ESB。
簡単に使ってみた限りでは、多少分かり難い印象あり。

今回は、以下の環境を使って文字列を加工して標準出力へ出力するような簡単なサンプルを作ってみた。

  • Spring Integration 1.0.2 SR1

サンプル作成

サービスクラスを POJO で作成。

TestService.java
package fits.sample;

public class TestService {

    public String hello(String name) {
        return "hello " + name;
    }
}

構成を XML で記述。

sample.xml
<beans:beans xmlns="http://www.springframework.org/schema/integration"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:stream="http://www.springframework.org/schema/integration/stream"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/integration
            http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
            http://www.springframework.org/schema/integration/stream
            http://www.springframework.org/schema/integration/stream/spring-integration-stream-1.0.xsd"
>

    <!-- 入力チャネルの設定 -->
    <channel id="input" />

    <!-- 出力チャネルの設定(標準出力へ出力) -->
    <stream:stdout-channel-adapter id="output" append-newline="true" />

    <!-- サービスの定義 -->
    <service-activator input-channel="input" output-channel="output"
        ref="testService" method="hello" />

    <!-- サービスクラス -->
    <beans:bean id="testService" class="fits.sample.TestService" />
</beans:beans>

実行クラスを作成。

TestMain.java
package fits.sample;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.channel.BeanFactoryChannelResolver;
import org.springframework.integration.channel.ChannelResolver;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.message.StringMessage;

public class TestMain {

    public static void main(String[] args) throws Exception {

        //CLASSPATH から sample.xml ファイルを探し出し、
        //ApplicationContext として読み込む
        AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("sample.xml", TestMain.class);

        ChannelResolver channelResolver = new BeanFactoryChannelResolver(ctx);

        //入力チャネルを取得
        MessageChannel inputChannel = channelResolver.resolveChannelName("input");
        //入力チャネルに文字列を送信
        inputChannel.send(new StringMessage("World"));

        ctx.stop();
    }
}

CLASSPATH に Spring Integration 内の JAR ファイルを追加し、TestMain クラスを実行。
事前に sample.xml ファイルを TestMain.class ファイルと同じ場所に配置しておく。(実際は、CLASSPATH から TestMain と同等のパッケージ構成となる場所に配置すればよい)

>java fits.sample.TestMain
・・・
hello World
・・・

アノテーションを使ったサンプル

先程のサンプルのアノテーション版を作成してみる。
TestMain クラスはそのまま再利用し、sample.xml と TestService クラスをアノテーション対応に変更する。

せっかくアノテーションを使ってるのに XML の構成ファイルを使うのはイマイチな気がしたが、今回は他の手段を見つけられなかった。(ClassPathXmlApplicationContext の箇所を別クラスにするだけだと思うが・・・)

TestService.java
package fits.sample;

import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.ServiceActivator;

@MessageEndpoint
public class TestService {

    //入出力チャネルの名称を定義
    @ServiceActivator(inputChannel="input", outputChannel="output")
    public String hello(String name) {
        return "hello " + name;
    }
}
sample.xml
<beans:beans xmlns="http://www.springframework.org/schema/integration"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:stream="http://www.springframework.org/schema/integration/stream"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/integration
            http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-2.5.xsd
            http://www.springframework.org/schema/integration/stream
            http://www.springframework.org/schema/integration/stream/spring-integration-stream-1.0.xsd"
>

    <channel id="input" />
    <stream:stdout-channel-adapter id="output" append-newline="true" />

    <!-- アノテーション使用の設定 -->
    <annotation-config />

    <!-- アノテーションクラスを検索するパッケージ定義 -->
    <context:component-scan base-package="fits.sample" />
</beans:beans>

TestMain クラスの実行結果は先程のサンプルと同じ。


なお、今回のサンプルのファイル構成は、

  • conf/fits/sample/sample.xml
  • src/fits/sample/TestMain.java
  • src/fits/sample/TestService.java

ビルドや実行に使った Ant 定義ファイルは以下。

build.xml
<project name="Spring Integration Sample" default="compile" basedir=".">
    <property name="conf.dir" value="conf" />
    <property name="src.dir" value="src" />
    <property name="dest.dir" value="dest" />

    <path id="spring.classpath">
        <fileset dir="D:\spring-integration-1.0.2.SR1">
            <include name="**/*.jar" />
        </fileset>
    </path>

    <path id="project.classpath">
        <pathelement path="${dest.dir}" />
        <pathelement path="${conf.dir}" />
        <path refid="spring.classpath" />
    </path>

    <target name="compile">
        <mkdir dir="${dest.dir}" />

        <javac srcdir="${src.dir}" destdir="${dest.dir}">
            <classpath refid="spring.classpath" />
        </javac>
    </target>

    <target name="run" depends="compile">
        <java fork="true" className="fits.sample.TestMain">
            <classpath refid="project.classpath"/>
        </java>
    </target>

    <target name="clean">
        <delete dir="${dest.dir}" />
    </target>
</project>