2013年12月23日月曜日

Spring の JMS サンプルを試す

この記事は Spring Framework Advent Calendar 2013 の 12/23 の記事です。 

このエントリでは、Spring Guide で紹介されている JMS サンプルを試してみたいと思います。
# なんども掲載日を変更してしまい、すみません。
# 本当は WildFly/HornetQ で何かしら動かしてみたかったのですが、次回リベンジします。。

Spring では Guides として、用途別にたくさんのサンプルを載せています。

http://spring.io/guides

その中で JMS を利用したメッセージングのサンプルがあったので、試してみました。

http://spring.io/guides/gs/messaging-jms/

サンプルを clone し、内容を確認してみます。
$ git clone https://github.com/spring-guides/gs-messaging-jms.git
$ cd gs-messaging-jms
$ tree --dirsfirst
.
# 完成形
├── complete
│   ├── gradle
│   │   └── wrapper
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── hello
│   │               ├── Application.java
│   │               └── Receiver.java
│   ├── build.gradle
│   ├── gradlew
│   ├── gradlew.bat
│   └── pom.xml
# 最初の状態
├── initial
│   ├── gradle
│   │   └── wrapper
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── hello
│   ├── build.gradle
│   ├── gradlew
│   ├── gradlew.bat
│   └── pom.xml
# その他
├── test
│   └── run.sh
├── LICENSE.code.txt
├── LICENSE.writing.txt
├── README.adoc
├── SIDEBAR.ftl.md
└── SIDEBAR.md

complete に完成済みの答えが格納されています。initial はある程度の構成ができてここからソースや少々の設定を加えて complete に近づけていく、という形になっています。
今回作成する必要があるのは、
  • Application.java
  • Receiver.java
ですね。あとは Maven を利用するならば pom.xml を、Gradle であれば build.gradle を一部追記しておしまいです。では、ガイド に沿って、initial 以下を編集作成していきたいと思います。

Receiver.java

hello パッケージに Receiver.java を作成します。
MDB ? と見まごうばかりですが、これは Message Driven Pojo(MDP) であり、javax.jms.MessageListener を実装する必要はありません。onMessage ではなく、任意の名前のメソッドを作成し、メッセージコンシューマの実装を記述していきます。
最後の FileSystemUtils.deleteRecursively(new File("activemq-data")); で組込 ActiveMQ のデータを削除しています。

Application.java

hello パッケージに Application.java を作成します。

まず目をひくのが、Class 宣言のところにある @Configuration と @EnableAutoConfiguration ですね。このプロジェクトは、Spring Boot というスタンドアロンなアプリケーションを迅速につくる仕組みを利用しており、この 2 つの設定のおかげで、だいたい Spring が設定をよきにはからってくれるというもののようです。確かに、プロジェクト中に applicationContext.xml などは見当たりません。すごい。

Spring Boot - AutoConfigure

とはいえ、自分で設定するところも必要です。

L27 - 30 では先ほど作成した Receiver を Bean 定義しています。Java クラス中に定義できてしまうんですね。
L32 - 39 では、メッセージ受信時に実行されるメソッドが定義するために、Receiver#receiveMessage をリスナ用メソッドに指定しています。Receiver が MDP でいられるのはこういった設定ができるからなんですねえ。
L41 - 52 では、SimpleMessageListenerContainer を返す container メソッドを定義しています。ここで MDP の設定はひと通り定義しています。

main() メソッドが、送信クライアントになっています。JmsTemplate を使っているので、かなりコードが短いですね。
# 送信に関しては、JMS2.0 もかなりシンプルに使える API ですので、EE 7 が待ち遠しいですね。

アプリケーションのビルド・実行

initial にある pom.xml/build.gradle に plugin を追加して、実行可能な jar を作成できるようにします。pom.xml の場合は spring-boot-maven-plugin プラグインを追加し、build.gradle の場合は dependencies と apply plugin を追加します。

Maven の場合


Gradle の場合


こう並べてみると Gradle は記述がさっぱりしていて、ぐらついてしまいますねえ。。

これでビルドできるようになったので、Maven または Gradle を使ってビルドします。

Maven の場合

$ mvn clean package

Gradle の場合

$ ./gradlew build

ビルドが完了したら実行します。

Maven の場合

$ java -jar target/gs-messaging-jms-0.1.0.jar

Gradle の場合

$ java -jar build/libs/gs-messaging-jms-0.1.0.jar

実行結果

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::             (v0.5.0.M6)

[...]
Sending a new message.
Received <ping>
[...]

Spring + JMS いい感じ

Spring の JMS クライアントはかなりいい感じということがわかりました。純粋に jms クライアントを書くよりシンプルに記述できますね。
また、MDP を使うことで EJB なしで非同期受信ができるのは特筆すべき点と思います。

今回の JMS プロバイダは組込みの ActiveMQ でしたが、今後は WildFly の JMS プロバイダである HornetQ を利用するなどもしてみようかと思います。

0 件のコメント:

コメントを投稿