このエントリでは、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
Receiver.java
hello パッケージに Receiver.java を作成します。
MDB ? と見まごうばかりですが、これは Message Driven Pojo(MDP) であり、javax.jms.MessageListener を実装する必要はありません。onMessage ではなく、任意の名前のメソッドを作成し、メッセージコンシューマの実装を記述していきます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package hello; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.context.ConfigurableApplicationContext; | |
import org.springframework.util.FileSystemUtils; | |
import java.io.File; | |
public class Receiver { | |
/** | |
* Get a copy of the application context | |
*/ | |
@Autowired | |
ConfigurableApplicationContext context; | |
/** | |
* When you receive a message, print it out, then shut down the application. | |
* Finally, clean up any ActiveMQ server stuff. | |
* @param message | |
*/ | |
public void receiveMessage(String message) { | |
System.out.println("Received <" + message + ">"); | |
context.close(); | |
FileSystemUtils.deleteRecursively(new File("activemq-data")); | |
} | |
} |
最後の FileSystemUtils.deleteRecursively(new File("activemq-data")); で組込 ActiveMQ のデータを削除しています。
Application.java
hello パッケージに Application.java を作成します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package hello; | |
import javax.jms.ConnectionFactory; | |
import javax.jms.JMSException; | |
import javax.jms.Message; | |
import javax.jms.Session; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | |
import org.springframework.context.ConfigurableApplicationContext; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.jms.core.JmsTemplate; | |
import org.springframework.jms.core.MessageCreator; | |
import org.springframework.jms.listener.SimpleMessageListenerContainer; | |
import org.springframework.jms.listener.adapter.MessageListenerAdapter; | |
import org.springframework.util.FileSystemUtils; | |
import java.io.File; | |
@Configuration | |
@EnableAutoConfiguration | |
public class Application { | |
static String mailboxDestination = "mailbox-destination"; | |
@Bean | |
Receiver receiver() { | |
return new Receiver(); | |
} | |
@Bean | |
MessageListenerAdapter adapter(Receiver receiver) { | |
return new MessageListenerAdapter(receiver) { | |
{ | |
setDefaultListenerMethod("receiveMessage"); | |
} | |
}; | |
} | |
@Bean | |
SimpleMessageListenerContainer container(final MessageListenerAdapter messageListener, | |
final ConnectionFactory connectionFactory) { | |
return new SimpleMessageListenerContainer() { | |
{ | |
setMessageListener(messageListener); | |
setConnectionFactory(connectionFactory); | |
setDestinationName(mailboxDestination); | |
setPubSubDomain(true); | |
} | |
}; | |
} | |
public static void main(String[] args) { | |
// Clean out any ActiveMQ data from a previous run | |
FileSystemUtils.deleteRecursively(new File("activemq-data")); | |
// Launch the application | |
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); | |
// Send a message | |
MessageCreator messageCreator = new MessageCreator() { | |
@Override | |
public Message createMessage(Session session) throws JMSException { | |
return session.createTextMessage("ping!"); | |
} | |
}; | |
JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class); | |
System.out.println("Sending a new message."); | |
jmsTemplate.send(mailboxDestination, messageCreator); | |
} | |
} |
まず目をひくのが、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 が待ち遠しいですね。
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 の場合
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>org.springframework</groupId> | |
<artifactId>gs-messaging-jms</artifactId> | |
<version>0.1.0</version> | |
<parent> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-starter-parent</artifactId> | |
<version>0.5.0.M6</version> | |
</parent> | |
<dependencies> | |
<dependency> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-starter</artifactId> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-jms</artifactId> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.activemq</groupId> | |
<artifactId>activemq-core</artifactId> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.geronimo.specs</groupId> | |
<artifactId>geronimo-jms_1.1_spec</artifactId> | |
<version>1.1</version> | |
</dependency> | |
</dependencies> | |
<build> | |
<plugins> | |
<plugin> | |
<artifactId>maven-compiler-plugin</artifactId> | |
<version>2.3.2</version> | |
</plugin> | |
<plugin> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-maven-plugin</artifactId> | |
</plugin> | |
</plugins> | |
</build> | |
<repositories> | |
<repository> | |
<id>spring-snapshots</id> | |
<url>http://repo.spring.io/libs-snapshot</url> | |
<snapshots><enabled>true</enabled></snapshots> | |
</repository> | |
<repository> | |
<id>spring-releases</id> | |
<url>http://repo.spring.io/release</url> | |
<snapshots><enabled>true</enabled></snapshots> | |
</repository> | |
</repositories> | |
<pluginRepositories> | |
<pluginRepository> | |
<id>spring-snapshots</id> | |
<url>http://repo.spring.io/libs-snapshot</url> | |
<snapshots><enabled>true</enabled></snapshots> | |
</pluginRepository> | |
</pluginRepositories> | |
</project> |
Gradle の場合
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
buildscript { | |
repositories { | |
maven { url "http://repo.spring.io/libs-snapshot" } | |
mavenLocal() | |
} | |
dependencies { | |
classpath("org.springframework.boot:spring-boot-gradle-plugin:0.5.0.M6") | |
} | |
} | |
apply plugin: 'java' | |
apply plugin: 'eclipse' | |
apply plugin: 'idea' | |
apply plugin: 'spring-boot' | |
jar { | |
baseName = 'gs-messaging-jms' | |
version = '0.1.0' | |
} | |
repositories { | |
mavenCentral() | |
maven { url "http://repo.spring.io/libs-snapshot" } | |
} | |
dependencies { | |
compile("org.springframework.boot:spring-boot-starter:0.5.0.M6") | |
compile("org.springframework:spring-jms:4.0.0.RC1") | |
compile("org.apache.activemq:activemq-core:5.4.0") | |
compile("org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1") | |
testCompile("junit:junit:4.11") | |
} | |
task wrapper(type: Wrapper) { | |
gradleVersion = '1.8' | |
} |
これでビルドできるようになったので、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 件のコメント:
コメントを投稿