JMS

异步消息

  消息是通过网络从一个系统异步传送给另一个系统的,发送者不需要等待接收者接收或者处理该消息,因此消息传送机制能够实现组件之间的高度解耦,即:发送者-消息服务器-接受者。

JMS

  JMS全称Java消息服务(Java Message Servicer),是一套java消息API,使用时需要提供者提供实现,常用的实现:ActiveMQ、RabbitMQ等。各个厂商实现消息机制的方案各不相同,导致了使用消息机制在不同的厂商之间切换的复杂性,为了统一消息API,Sun合作各消息提供者厂商统一出通用的消息接口,即 JMS API。
ActiveMQ安装:http://blog.csdn.net/u010845141/article/details/51778999
  

消息传送模型
点对点模型(P2P) one-to-one

JMS点对点模型

  消息发送者发送一条Message到Queue中,消息接收者从队列中接收一条消息,当有多个消息接收者时,该Message仅仅被接收一次,多消息接收者可使用负载均衡处理。

发布/订阅模型(Pub/Sub) one-to-many

JMS发布/订阅

  发布者发布一条Message到相应的Topic,订阅了该主题的订阅者都将收到该Message的一个副本。

JMS API

  下面的例子使用了ActiveMQ作为消息提供者,请参考ActiveMQ安装和使用:
 

ActiveMQ jar包 
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-all</artifactId>
    <version>5.13.3</version>
</dependency>
  • 公共API:
/**
 * 使用公共API发送消息,先启动ActiveMQ服务器后执行
 * 
 * @param args
 * @throws Exception
 */
public static void main(String[] args) throws Exception {
    //获取ActiveMQ连接工厂
    ConnectionFactory connFactory = new ActiveMQConnectionFactory();
    //获取到JMS提供者服务器连接
    Connection conn = connFactory.createConnection();       
    //创建Session
    Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
    //创建目的地,使用Queue
    Destination dest = session.createQueue("SampleQueue");
    //创建生产者
    MessageProducer prod = session.createProducer(dest);
    //创建消息实体
    Message msg = session.createTextMessage("Simples Assim");
    //启动Connection,可以收发消息
    conn.start();
    //发送消息
    prod.send(msg);     
    conn.close();
}

/**
 * 消息接收者,启动后如果没有消息接收,则阻塞;接收到消息后打印退出
 * @param args
 * @throws Exception
 */
    public static void main(String[] args) throws Exception{
    ConnectionFactory factory = new ActiveMQConnectionFactory();
    Connection conn = factory.createConnection();
    Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
    Destination dest = session.createQueue("SampleQueue");
    MessageConsumer consumer = session.createConsumer(dest);
    conn.start();
    TextMessage msg = (TextMessage)consumer.receive();
    System.out.println(msg.getText());
    conn.close();       
}
  • 点对点API
/**
 * 使用两个队列request1,request2,request1发送消息,request2接收处理结果
 * 发送 d1 = 1.0 ,d2 = 2.0,消息接收者求和,并发送消息返回
 * @author TT
 *
 */
public class One2OneSender {
    public static void main(String[] args)throws Exception {
        QueueConnectionFactory qFactory = new ActiveMQConnectionFactory();
        QueueConnection qConnect = qFactory.createQueueConnection();
        QueueSession qSession = qConnect.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        Queue requestQ = qSession.createQueue("request1");
        Queue responseQ = qSession.createQueue("response2");
        qConnect.start();       
        MapMessage msg = qSession.createMapMessage();
        msg.setDouble("d1", 1.0);
        msg.setDouble("d2", 2.0);
        //设置消息接收队列
        msg.setJMSReplyTo(responseQ);
        QueueSender qSender = qSession.createSender(requestQ);
        qSender.send(msg);

        QueueReceiver qReceiver = qSession.createReceiver(responseQ);
        TextMessage tmsg = (TextMessage)qReceiver.receive(30000);
        if(tmsg == null) {
            System.out.println("One2OneReceiver not responding.");
        }else {
            System.out.println("One2OneReceiver response was " + tmsg.getText());
        }
    }
}
/**
 * 该类实现消息监听器接口,注册为request1队列的消息接收者
 * 监听器处理类计算接收到的值并求和,发送接收到指定的队列request2
 * @author TT
 *
 */
public class One2OneReceiver implements MessageListener{

    private QueueConnection qConnect = null;
    private QueueSession qSession = null;
    private Queue requestQ = null;

    public One2OneReceiver(){
        try {
            QueueConnectionFactory connFactory = new ActiveMQConnectionFactory();
            qConnect = connFactory.createQueueConnection();
            qSession = qConnect.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            requestQ = qSession.createQueue("request1");
            qConnect.start();
            QueueReceiver receiver = qSession.createReceiver(requestQ);
            receiver.setMessageListener(this);
            System.out.println("Waiting for receive message...");
        }catch(JMSException jmse) {
            jmse.printStackTrace();
            System.exit(1);
        }   
    }

    public void onMessage(Message message) {
        MapMessage msg = (MapMessage)message;
        try {
            double d1 = msg.getDouble("d1");
            double d2 = msg.getDouble("d2");
            System.out.println("Sum : " + (d1 + d2));

            TextMessage tmsg = qSession.createTextMessage();
            tmsg.setText("" +(d1 + d2));
            tmsg.setJMSCorrelationID(message.getJMSMessageID());
            QueueSender sender = qSession.createSender((Queue)message.getJMSReplyTo());
            sender.send(tmsg);
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

    private void exit() {
        try {
            qConnect.close();
        }catch(JMSException e) {
            e.printStackTrace();
        }
        System.exit(0);
    }

    public static void main(String[] args) {
        One2OneReceiver receiver = new One2OneReceiver();
        try {
            BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Press enter to quit application.");
            stdin.readLine();
            receiver.exit();    
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}
  • 发布/订阅API
/**
 * 执行一次该程序,启动一个Chat,任意一个Chat发送的消息,其他Chat都可以接收到
 * 同时,该Chat也是该Topic的订阅者
 * 
 * 注:执行时,先启动ActiveMQ服务器
 */
public class TopicChat implements MessageListener{

    private TopicConnection connection;
    private TopicSession pubSession;
    private TopicPublisher publisher;
    private String username;

    public TopicChat(String username) throws Exception{
        TopicConnectionFactory connfactory = new ActiveMQConnectionFactory();
        TopicConnection connection = connfactory.createTopicConnection();
        //发布者Session和订阅者Session
        TopicSession pubSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
        TopicSession subSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
        //订阅主题
        Topic chatTopic = pubSession.createTopic("topic1");
        //发布者
        TopicPublisher publisher = pubSession.createPublisher(chatTopic);
        //订阅者,第三个参数标识自己不接受自己发送的消息
        TopicSubscriber subscriber = subSession.createSubscriber(chatTopic,null,true);
        //注册自己为订阅者监听器
        subscriber.setMessageListener(this);
        this.connection = connection;
        this.publisher = publisher;
        this.pubSession = pubSession;
        this.username = username;
        connection.start();
    }
    //接收消息处理事件
    public void onMessage(Message message) {
        try {
            TextMessage textMessage = (TextMessage)message;
            System.out.println(username + ": " + textMessage.getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

    protected void writeMessage(String text)throws JMSException {
        TextMessage msg = pubSession.createTextMessage();
        msg.setText(text);
        publisher.publish(msg);
    }

    public void close()throws JMSException{
        connection.close();
    }

    public static void main(String[] args) {
        String username = "INI_USERNAME";
        try {
            if(args.length > 0) {
                username = args[0];
            }
            TopicChat chat = new TopicChat(username);
            BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in));
            while(true){
                String s = commandLine.readLine();
                if(s.equalsIgnoreCase("exit")) {
                    chat.close();
                    System.exit(0);
                }else{
                    chat.writeMessage(s);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值