About

ドキュメント

Javadoc

モジュール

プロジェクト文書

Built by Maven

概要

S2JMS-Containerは、POJOがJMSのAPIを意識することなく、 非同期通信によるメッセージを受信できるようにするためのコンポーネントです。

通常、JMSによるインバウンドメッセージ受信アプリケーション (EJBのMessage-Driven Beanなど) を作成するには、以下の手順を踏みます。

  1. javax.jms.MessageListenerインターフェースを実装したクラスを作成する。
  2. onMessage(javax.jms.Message) メソッドを作成する。
  3. onMessage(javax.jms.Message) メソッドの中で、受信した javax.jms.Message を処理する。

しかし、この場合作成したクラスはJMSのAPIに依存することになってしまいます。

S2JMS-Containerを利用することで、JMSのAPIに依存しない受信アプリケーション (Message-Driven POJOs) を作ることができ、特に既存の資産をJMS受信アプリケーションに変換する際に威力を発揮します。

S2JMS-Containerの提供する機能

S2JMS-Containerは、以下の機能を提供します。

  1. メッセージリスナ・コンポーネントへJMSメッセージのバインド
  2. メッセージリスナ・コンポーネントの呼び出し
  3. 非Webコンテナ環境でSeasar2におけるrequestスコープの提供

JMSメッセージヘッダのバインド

メッセージリスナ・コンポーネントに対して、受信したJMSメッセージのヘッダをバインドします。

バインドしたいフィールドまたはsetterメソッドに @JMSHeader アノテーションを記述することで、 該当するメッセージヘッダがバインドされます。

以下のように、@JMSHeaderアノテーションのみを記述した場合、 フィールド名に一致するメッセージヘッダがバインドされます。 この場合、フィールド名は「correlationID」 (「JMS」というプレフィックスをつけない) または「JMSCorrelationID」 (「JMS」というプレフィックスをつける) のどちらでも有効です。

    @JMSHeader
    String correlationID;

以下のように、nameメンバを利用してヘッダ名称を記述することもできます。 この場合、フィールド名には関係なくnameメンバで指定されたヘッダ名が使用されます。 この場合もヘッダ名称には「JMS」プレフィックスをつけてもつけなくても構いません。

    @JMSHeader(name = "deliveryMode")
    int mode;

@JMSHeaderアノテーションには、 S2ContainerのbindingTypeメンバも指定することができます。

    @JMSHeader(bindingType = BindingType.MUST)
    String JMSMessageID;

bindingTypeについては、以下の表を参照してください。

bindingType 説明
MUST バインドに失敗した場合、例外が発生します。
SHOULD (デフォルト) バインドに失敗した場合、警告を通知します。
MAY バインドに失敗した場合、何もおきません。
NONE バインドを行いません。

setterメソッドに対しても@JMSHeaderアノテーションを記述することができます。 nameメンバを省略した場合、メソッド名から「set」を除いた部分がヘッダ名称として扱われます。

    int priority;
    
    @JMSHeader(name = "JMSPriority", bindingType = BindingType.MUST)
    public void setPriority(int priority) {
      this.priority = priority;
    }

JMSメッセージプロパティのバインド

ヘッダと同様にメッセージのプロパティもバインドすることができます。

以下のように、フィールドやsetterに@JMSPropertyアノテーションのみを記述した場合、 フィールド名に一致するメッセージプロパティがバインドされます。 この場合、「foo」という名前のプロパティがバインドされます。

  @JMSProperty
  int foo;
  @JMSProperty
  public void setFoo(int foo){
      this.foo = foo;
  }

また、以下のようにnameメンバを利用してプロパティ名を明示することもできます。

  @JMSProperty(name = "baz")
  public void setBar(String bar) {
      this.bar = bar;
  }

@JMSPropertyアノテーションにも、@JMSHeaderアノテーションと同様に、 bindingTypeメンバによるバインディングの制御を指定することができます。

JMSメッセージペイロードデータのバインド

ヘッダと同様にメッセージの本体 (ペイロードデータ) もバインドすることができます。

MapMessageを除いて、 以下のようにフィールドやsetterに@JMSPayloadアノテーションのみを記述した場合、 フィールド名に一致するメッセージプロパティがバインドされます。 この場合、TextMessageのペイロードデータがバインドされます。

  @JMSPayload
  String text;
  @JMSPayload
  public void setText(String text){
      this.text = text;
  }

MapMessageの場合、 以下のようにフィールドやsetterに@JMSPayloadアノテーションのみを記述した場合、 ペイロードデータからフィールド名に一致するマッピングの値がバインドされます。 この場合、MapMessageのペイロードデータから、 fooというキーにマッピングされている値がバインドされます。

  @JMSPayload
  int foo;
  @JMSPayload
  public void setFoo(int foo){
      this.foo = foo;
  }

また、以下のようにnameメンバを利用してキーを明示することもできます。

  @JMSPayload(name = "baz")
  public void setBar(String bar) {
      this.bar = bar;
  }

ただし、フィールドまたはプロパティの型がMapの場合は、 MapMessageのペイロードが持つ全てのマッピングを含んだMapがバインドされます。

  @JMSPayload
  public void setBaz(Map baz) {
      this.baz = baz;
  }

@JMSPayloadアノテーションにも、@JMSHeaderアノテーションと同様に、 bindingTypeメンバによるバインディングの制御を指定することができます。

リスナメソッド

受信したメッセージがバインドされた後に呼び出されるのがリスナメソッドです。

リスナメソッドは、デフォルトではメソッド名がonMessageのメソッドです。

  void onMessage() {
    ...
  }

引数を一つ持つこともできます。 引数の型はメッセージのペイロードデータ型か、javax.jms.Messageです。

  void onMessage(String text) {
    ...
  }
  void onMessage(Message message) {
    ...
  }

また、以下のように@OnMessageアノテーションで任意の名前のメソッドをリスナメソッドにすることができます。

  @OnMessage
  void some() {
    ...
  }
  @OnMessage
  void some(Map payload) {
    ...
  }

いずれも、戻り値の型は任意です。 S2JMS-Containerが戻り値を利用することはありません。