javax.jms及java消息机制

JMS(Java Message Service) 即Java消息服务。

它提供标准的产生、发送、接收消息的接口简化企业 应用的开发。它支持两种消息通信模型:

  1. 点到点(point-to-point)(P2P)模型
  2. 发布/订阅(Pub/Sub)模型

P2P 模型规定了一个消息只能有一个接收者;
Pub/Sub 模型允许一个消息可以有多个接收者

对于点到点模型,消息生产者产生一个消息后,把这个消息发送到一个Queue(队列)中,然后消息接收者再从这个Queue中读取,一旦这个消息被一个接收者读取之后,它就在这个Queue中消失了,所以一个消息只能被一个接收者消费

与点到点模型不同,发布/订阅模型中,消息生产者产生一个消息后,把这个消息发送到一个Topic中,这个Topic可以同时有多个接收者在监听,当一个消息到达这个Topic之后,所有消息接收者都会收到这个消息。


Destination :消息发送的目的地,也就是前面说的Queue和Topic。创建好一个消息之后,只需要把这个消息发送到目的地,消息的发送者就可以继续做自己的事情,而不用等待消息被处理完成。至于这个消息什么时候,会被哪个消费者消费,完全取决于消息的接受者。
Message :从字面上就可以看出是被发送的消息。它有下面几种类型:
StreamMessage: Java 数据流消息,用标准流操作来顺序的填充和读取。
MapMessage:一个Map类型的消息;名称为 string 类型,而值为 Java 的基本类型。
TextMessage:普通字符串消息,包含一个String。
ObjectMessage:对象消息,包含一个可序列化的Java 对象
BytesMessage:二进制数组消息,包含一个byte[]。
XMLMessage: 一个XML类型的消息。
最常用的是TextMessage和ObjectMessage。
Session: 与JMS提供者所建立的会话,通过Session我们才可以创建一个Message。
Connection: 与JMS提供者建立的一个连接。可以从这个连接创建一个会话,即Session。
ConnectionFactory: 那如何创建一个Connection呢?这就需要下面讲到的ConnectionFactory了。通过这个工厂类就可以得到一个与JMS提供者的连接,即Conection。
Producer: 消息的生产者,要发送一个消息,必须通过这个生产者来发送。
通过下面这个简图可以看出上面这些概念的关系。

ConnectionFactory—->Connection—>Session—>Message
Destination + Session————————————>Producer
Destination + Session————————————>MessageConsumer


Queue实现的是点到点模型

,在下面的例子中,启动2个消费者共同监听一个Queue,然后循环给这个Queue中发送多个消息,我们依然采用ActiveMQ。

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;

public class QueueTest {
    public static void main(String[] args) throws Exception {
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");

        Connection connection = factory.createConnection();
        connection.start();


        //创建一个Queue
        Queue queue = new ActiveMQQueue("testQueue");
        //创建一个Session
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);


        //注册消费者1
        MessageConsumer comsumer1 = session.createConsumer(queue);
        comsumer1.setMessageListener(new MessageListener(){
            public void onMessage(Message m) {
                try {
                    System.out.println("Consumer1 get " + ((TextMessage)m).getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });


        //注册消费者2
        MessageConsumer comsumer2 = session.createConsumer(queue);
        comsumer2.setMessageListener(new MessageListener(){
            public void onMessage(Message m) {
                try {
                    System.out.println("Consumer2 get " + ((TextMessage)m).getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }

        });


        //创建一个生产者,然后发送多个消息。
        MessageProducer producer = session.createProducer(queue);
        for(int i=0; i<10; i++){
            producer.send(session.createTextMessage("Message:" + i));
        }
    }
}

运行这个例子会得到下面的输出结果:

Consumer1 get Message:0
Consumer2 get Message:1
Consumer1 get Message:2
Consumer2 get Message:3
Consumer1 get Message:4
Consumer2 get Message:5
Consumer1 get Message:6
Consumer2 get Message:7
Consumer1 get Message:8
Consumer2 get Message:9

可以看出每个消息直被消费了一次,但是如果有多个消费者同时监听一个Queue的话,无法确定一个消息最终会被哪一个消费者消费。


Topic实现的是发布/订阅模型

与Queue不同的是,Topic实现的是发布/订阅模型,在下面的例子中,启动2个消费者共同监听一个Topic,然后循环给这个Topic中发送多个消息。

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQTopic;

public class TopicTest {
    public static void main(String[] args) throws Exception {
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");

        Connection connection = factory.createConnection();
        connection.start();

        //创建一个Topic
        Topic topic= new ActiveMQTopic("testTopic");
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        //注册消费者1
        MessageConsumer comsumer1 = session.createConsumer(topic);
        comsumer1.setMessageListener(new MessageListener(){
            public void onMessage(Message m) {
                try {
                    System.out.println("Consumer1 get " + ((TextMessage)m).getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });

        //注册消费者2
        MessageConsumer comsumer2 = session.createConsumer(topic);
        comsumer2.setMessageListener(new MessageListener(){
            public void onMessage(Message m) {
                try {
                    System.out.println("Consumer2 get " + ((TextMessage)m).getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }

        });

        //创建一个生产者,然后发送多个消息。
        MessageProducer producer = session.createProducer(topic);
        for(int i=0; i<10; i++){
            producer.send(session.createTextMessage("Message:" + i));
        }
    }
}

运行后得到下面的输出结果:

Consumer1 get Message:0
Consumer2 get Message:0
Consumer1 get Message:1
Consumer2 get Message:1
Consumer1 get Message:2
Consumer2 get Message:2
Consumer1 get Message:3
Consumer2 get Message:3
Consumer1 get Message:4
Consumer2 get Message:4
Consumer1 get Message:5
Consumer2 get Message:5
Consumer1 get Message:6
Consumer2 get Message:6
Consumer1 get Message:7
Consumer2 get Message:7
Consumer1 get Message:8
Consumer2 get Message:8
Consumer1 get Message:9
Consumer2 get Message:9

JMSReplyTo

在下面的例子中,首先创建两个Queue,发送者给一个Queue发送,接收者接收到消息之后给另一个Queue回复一个Message,然后再创建一个消费者来接受所回复的消息。

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
public class MessageSendReceiveAndReply {
    public static void main(String[] args) throws Exception {
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");

        Connection connection = factory.createConnection();
        connection.start();

        //消息发送到这个Queue
        Queue queue = new ActiveMQQueue("testQueue");
        //消息回复到这个Queue
        Queue replyQueue = new ActiveMQQueue("replyQueue");

        final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建一个消息,并设置它的JMSReplyTo为replyQueue。
        Message message = session.createTextMessage("Andy");
        message.setJMSReplyTo(replyQueue);

        MessageProducer producer = session.createProducer(queue);
        producer.send(message);

        //消息的接收者
        MessageConsumer comsumer = session.createConsumer(queue);
        comsumer.setMessageListener(new MessageListener(){
            public void onMessage(Message m) {
                try {
                    //创建一个新的MessageProducer来发送一个回复消息。
                    MessageProducer producer = session.createProducer(m.getJMSReplyTo());
                    producer.send(session.createTextMessage("Hello " + ((TextMessage) m).getText()));
                } catch (JMSException e1) {
                    e1.printStackTrace();
                }
            }

        });

        //这个接收者用来接收回复的消息
        MessageConsumer comsumer2 = session.createConsumer(replyQueue);
        comsumer2.setMessageListener(new MessageListener(){
            public void onMessage(Message m) {
                try {
                    System.out.println(((TextMessage) m).getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

首先消息生产者发送一个消息,内容为“Andy”, 然后消费者收到这个消息之后根据消息的JMSReplyTo,回复一个消息,内容为“Hello Andy‘。 最后在回复的Queue上创建一个接收回复消息的消费者,它输出所回复的内容。

运行上面的程序,可以得到下面的输出结果:
Hello Andy

原文:http://blog.csdn.net/zhangxs_3/article/category/625599

Classes contained in javax.jms.jar: javax.transaction.xa.XAResource.class javax.jms.BytesMessage.class javax.jms.Message.class javax.jms.JMSException.class javax.jms.Destination.class javax.jms.DeliveryMode.class javax.jms.Connection.class javax.jms.Session.class javax.jms.ConnectionMetaData.class javax.jms.ExceptionListener.class javax.jms.ServerSessionPool.class javax.jms.ConnectionConsumer.class javax.jms.Topic.class javax.jms.MapMessage.class javax.jms.ObjectMessage.class javax.jms.StreamMessage.class javax.jms.TextMessage.class javax.jms.MessageListener.class javax.jms.MessageProducer.class javax.jms.MessageConsumer.class javax.jms.Queue.class javax.jms.TopicSubscriber.class javax.jms.QueueBrowser.class javax.jms.TemporaryQueue.class javax.jms.TemporaryTopic.class javax.jms.ServerSession.class javax.jms.ConnectionFactory.class javax.jms.MessageNotReadableException.class javax.jms.MessageNotWriteableException.class javax.jms.QueueConnection.class javax.jms.QueueSession.class javax.jms.QueueReceiver.class javax.jms.QueueSender.class javax.jms.QueueConnectionFactory.class javax.jms.QueueRequestor.class javax.jms.TopicConnection.class javax.jms.TopicSession.class javax.jms.TopicPublisher.class javax.jms.TopicConnectionFactory.class javax.jms.TopicRequestor.class javax.jms.XAConnection.class javax.jms.XASession.class javax.jms.XAConnectionFactory.class javax.jms.XAQueueConnection.class javax.jms.XAQueueSession.class javax.jms.XAQueueConnectionFactory.class javax.jms.XATopicConnection.class javax.jms.XATopicSession.class javax.jms.XATopicConnectionFactory.class javax.jms.MessageEOFException.class javax.jms.TransactionRolledBackException.class javax.jms.MessageFormatException.class javax.jms.IllegalStateException.class javax.jms.JMSSecurityException.class javax.jms.ResourceAllocationException.class javax.jms.TransactionInProgressException.class javax.jms.InvalidDestinationException.class javax.jms.InvalidClientIDException.class javax.jms.InvalidSelectorException.class
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值