JMS(Java Messaging Service)を利用すると他オブジェクトへ非同期で処理を依頼することができるようになります。
Servletなどでメールの大量送信を伴うような処理は非同期で行ったほうがいいかもしれない。

今回はJMSの実装であるAcitveMQを使用するため以下からダウンロード
http://activemq.apache.org/download.html
解凍して出てきたフォルダのlib以下をパスの通っているところへ配置する。



ActiveMQの流れ〜

・JMSサーバ(ActiveMQ)起動
・受信時に実行するクラス(キュー)をActiveMQに登録
・クライアントアプリケーションがActiveMQへメッセージ送信すると、ActiveMQは渡されたキーに該当するクラス(キュー)へメッセージを渡す
・メッセージを受け取ったクラス(キュー)はそのメッセージを元に処理を開始する


クライアントアプリケーション>>>>>JMSサーバ(ActiveMQ)>>>>>キュー(実行するクラス)

後述するお試しクラスを試したい場合は以下の通り

activeMQフォルダのbin\activemq.batを実行してActiveMQサーバ起動
・JmsReceiverクラスを実行するとActiveMQに登録して処理待ちの状態で待機
・TestJmsを実行するとActiveMQにメッセージが送信されて、ActiveMQがJmsReceiverを実行させる

とコンソールに名前などが出力されます




以下がメッセージを受信した時に実行されるクラス

import javax.jms.JMSException;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
 
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
 
 
public class JmsReceiver {
  public static boolean bQuit = false;
  
  public static void main(String[] args) {
    QueueConnection connection = null;
    QueueSession session = null;
    QueueReceiver receiver = null;
    
    try{
      ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_BROKER_URL);
      connection = factory.createQueueConnection();
      
      session = connection.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
      Queue queue = session.createQueue("TestQueue");
      
      receiver = session.createReceiver(queue);
      
      connection.start();
      
      while(!bQuit) {
        ObjectMessage msg = (ObjectMessage)receiver.receive();
        TestJmsMessage mes = (TestJmsMessage)msg.getObject();
        
        System.out.println(mes.getName());
        System.out.println(mes.getAddress());
        System.out.println(mes.getAge());
      }
           
    } catch (JMSException e) {
      e.printStackTrace();
 
    } finally {
      try {
        if (receiver != null) {
          receiver.close();
        }
        if (session != null) {
          session.close();
        }
        if (connection != null) {
          connection.close();
        }
        
  } catch (JMSException e) {
    e.printStackTrace();
  }
    }
  }
} 

今回登録するキューID(キー)は""TestQueue""となっている。
コネクション作成クラス(ActiveMQConnectionFactory)を生成し、それを元にセッションを作成する。
セッションにキュー判別用のキー(TestQueue)をセットし、それを元にレシーバオブジェクトを生成する。
connection.start()でコネクションが確立されます。


receiver.receive()が実行された段階で、メッセージ受信まで待機状態になる。
メッセージ受信するとmsg.getObject()でメッセージを受信し、内容をSystem.out.printlnする。
while(!bQuit)は常にFalseなので、receiver.receive()でまた待機状態になる。






以下がメッセージ送信するクラス

import java.io.Serializable;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
 
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
 
public class TestJms {
  
  public static void main(String[] args){
 
    long startTime = System.currentTimeMillis();
 
    QueueConnection connection = null;
    QueueSession session = null;
    QueueSender sender = null;
 
    try {
 
      QueueConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_BROKER_URL);
      connection = factory.createQueueConnection();
      
      session = connection.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
      Queue queue = session.createQueue("TestQueue");
      sender= session.createSender(queue);
      
      connection.start();
      
      TestJmsMessage mes = new TestJmsMessage();
      mes.setName("java_tarou");
      mes.setAddress("tokyo");
      mes.setAge(28);

 
      Message msg = session.createObjectMessage((Serializable)mes);
 
      sender.send(msg);
 
    } catch (JMSException e) {
      e.printStackTrace();
 
    } finally {
      try {
        if (sender != null) {
      sender.close();
        }
        if (session != null) {
          session.close();
        }
        if (connection != null) {
          connection.close();
        }
  } catch (JMSException e) {
    e.printStackTrace();
  }
    }
 
    long endTime = System.currentTimeMillis();
 
    System.out.println( "TestJms:" + (endTime - startTime) );
  }
} 

キューIDをセッションに登録するまでは同じ。
送信内容をMessageオブジェクトに変換した後で、sender.send()する。


Messageとして生成する対象はSerializableでないとダメ。

メッセージ内容のオブジェクト

import java.io.Serializable;

public class TestJmsMessage implements Serializable{
  public String name;
  public String address;
  public int age;
  
  
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getAddress() {
    return address;
  }
  public void setAddress(String address) {
    this.address = address;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
}