JMS学习之理论基础
本文代码使用ActiveMq5.6
一、什么是JMS
JMS(Java Message Service,Java消息服务)是一组Java应用程序接口(Java API),它提供创建、发送、接收、读取消息的服务。它给消息中间件生产商提供了一个统一API的标准。
第一个版本1998年,目前最新的2.0版本(2013年第一季度发布)
JMS规范地址:
http://www.oracle.com/technetwork/java/docs-136352.html(1.1版本)
http://download.oracle.com/otndocs/jcp/jms-2_0-fr-eval-spec/index.html(2.0版本)
中间件(MOM):中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。也就是应用程序A与应用程序B之间不是直接交互,而是通过中间件进行资源共享。

Active MQ的主要功能就是实现JMS Provider,用来实现高可用、高性能、可伸缩、易用、安全的企业级面向消息服务的系统。
消息中间件的功能:将信息按照消息的形式,从一个应用程序传输到另一个或多个应用程序。
消息中间件的特点:
- 消息的接受是异步,犹如发短信,发送消息的人不必等待接受消息人的响应,以此减少多系统之间的耦合度。
- 消息的可靠性,为确保消息在中间节可靠保存,只有在接受方收到消息后,才删除消息,多个消息也可以组册原子事务。
应用场景:多个系统间通讯的时候,一般需要保证:
- 可靠传输,数据不可以丢失,有的时候,也会保证数据不可以重复传输。
- 异步传输,多个系统同步调用会因为互相等待而造成系统瓶颈。
二、JMS消息模型
1、JMS元素
JMS provider:An implementation of the JMS interface for a Message Oriented Middleware (MOM) 面向消息中间件的JMS接口的实现
JMS client:An application or process that produces and/or receives messages. 产生和/或接收消息的应用程序或过程
JMS producer/publisher:A JMS client that creates and sends messages. 创建和发送消息的JMS客户端。
JMS consumer/subscriber:A JMS client that receives messages. 接收消息的JMS客户机。
JMS message(header/payload):An object that contains the data being transferred between JMS clients. 包含JMS客户机之间传输数据的对象
JMS queue:A staging area that contains messages that have been sent and are waiting to be read. A JMS queue only guarantees that each message is processed only once.包含已发送并等待被读取的消息的暂存区域。JMS队列只保证每个消息只处理一次。
JMS topic:A distribution mechanism for publishing messages that are delivered to multiple subscribers. 发布消息传递给多个订阅服务器的分发机制。
2、JMS消息模型
a、点对点的消息模型: 每个消息只能有一个消费者。

消息的生产者和消费者之间没有时间上的相关性。无论消费者在生产者发送消息的时候是否处于运行状态,它都可以提取消息。
b、发布订阅消息模型 每个消息可以有多个消费者

生产者和消费者之间有时间上的相关性。订阅一个主题的消费者只能消费自它订阅之后发布的消息。JMS规范允许客户创建持久订阅,这在一定程度上放松了时间上的相关性要求。持久订阅允许消费者消费它在未处于激活状态时发送的消息。
三、JMS消息接口
JMS支持两种消息类型P -to- P 和 Pub-Sub 这两种消息类型都继承统一接口JMS Parent,主要接口是
|
JMS Parent |
P -to -P |
Pub - Sub |
|
ConnectionFactory |
QueueConnectionFactory |
TopicConnectionFactory |
|
Connection |
QueueConnection |
TopicConnection |
|
Destination |
QueueDestination |
TopicDestination |
|
Session |
QueueSession |
TopicSession |
|
MessageProducer |
QueueSender |
TopicPublisher |
|
MessageConsumer |
QueueReceiver |
TopicSubscriber |
1、接口描述:
ConnectionFactory:连接工厂,JMS创建连接的方式
Connection:JMS客户端与JMS Provider的连接(通过ConnectionFactory创建的)。
Destination:消息的目的地
Session:一个接收或发送消息的一次回话
MessageProducer:由session对象创建的用于发送消息的对象
MessageConsumer:由session对象创建的用来接收消息的对象
2、JMS的创建流程

- 创建ConnectionFactory工厂
- 通过工厂创建Connection连接
- 通过连接创建一个连接回话Session
- 通过Session创建消息的生产者MessageProducer和消息的消费者MessageConsumer;同时Session也创建一个消息Mesage。
- 消息的生产者MessageProducer将该消息发送到目的地中Destination;消费者同时监听该消息目的地Destination。
P -to- P模型:

生产者:
package com.jalja.org.base.JMS;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
public class ProducerJMS {
private static String url="http://localhost:61616";//ActiveMq的地址
private static String queueName="queue-ch2";//创建一个队列
public static void main(String[] args) throws JMSException {
//
ConnectionFactory connFactory = new ActiveMQConnectionFactory();
Connection conn = connFactory.createConnection();
conn.start();//开启连接
//创建Session
Session session = conn.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
//创建一个p -to -P 类型的消息队列(消息目的地)
Destination des = session.createQueue(queueName);
//将消息交给消息发送者
MessageProducer producer = session.createProducer(des);
//创建一个text类型的消息
TextMessage msg = session.createTextMessage();
msg.setText("Hello World!");
//将消息发送到消息队列中
producer.send(msg);
//关闭资源
session.close();
conn.close();
}
}
消费者
package com.jalja.org.base.JMS;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnectionFactory;
public class ConsumerA {
private static String url = "tcp://localhost:61616";
private static String queueName = "queue-ch2";
public static void main(String[] args) throws Exception {
ConnectionFactory connFactory = new ActiveMQConnectionFactory();
Connection conn = connFactory.createConnection();
conn.start();//启动连接
//创建Session
Session session = conn.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
//创建一个p -to -P 类型的消息队列(消息目的地)
Destination des = session.createQueue(queueName);
//创建一个消息消费者 并指定其消费信息的目的地
MessageConsumer consumer = session.createConsumer(des);
//监听消息队列
Listener listener = new Listener();
listener.setForm("ConsumerA");
consumer.setMessageListener(listener); }
}
消息监听器:
package com.jalja.org.base.JMS;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class Listener implements MessageListener {
private String form = null;
/**
* 监听消息队列,如果该消息队列有消息,该监听器就可以获取消息
*/
@Override
public void onMessage(Message message) {
TextMessage msg = (TextMessage)message;
try {
System.out.println(getForm() + ":" + msg.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
public String getForm() {
return form;
}
public void setForm(String form) {
this.form = form;
} }
Pub - Sub 模型

生产者:
package ch02.pubsub; import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory; /*
* pubsub MQ生产者
*/
public class Publisher {
private static String url = "tcp://localhost:8161";
private static String topicName = "topic.ch02";
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ConnectionFactory connFactory = new ActiveMQConnectionFactory();
Connection conn = connFactory.createConnection();
conn.start();
Session session = conn.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
Destination des = session.createTopic(topicName);
MessageProducer publisher = session.createProducer(des);
TextMessage msg = session.createTextMessage();
msg.setText("Hello World!");
publisher.send(msg);
session.close();
conn.close();
}
}
消费者:
package ch02.pubsub; import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session; import org.apache.activemq.ActiveMQConnectionFactory; /**
*
* PTP 消费者A
*
*/
public class SubscriberA { private static String url = "tcp://localhost:8161";
private static String topicName = "topic.ch02"; /**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ConnectionFactory connFactory = new ActiveMQConnectionFactory();
Connection conn = connFactory.createConnection();
conn.start();
Session session = conn.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
Destination des = session.createTopic(topicName);
MessageConsumer consumer = session.createConsumer(des);
Listener listener = new Listener();
listener.setForm("SubscriberA");
consumer.setMessageListener(listener); } }
消息监听器:
package ch02.pubsub; import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage; public class Listener implements MessageListener { private String form = null; @Override
public void onMessage(Message message) {
TextMessage msg = (TextMessage)message;
try {
System.out.println(getForm() + ":" + msg.getText());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public String getForm() {
return form;
} public void setForm(String form) {
this.form = form;
} }
JMS学习之理论基础的更多相关文章
- ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习
转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...
- JMS学习(三)JMS 消息结构之属性及消息体详解
一.前言 通过上一篇的学习我们知道了消息分为三个部分,即消息头,属性及消息体,并对消息头的十个属性进行了详细的介绍,本文再对消息属性及消息体进行详细的介绍. 二.属性介绍 消息属性的主要作用是可以对头 ...
- JMS学习的个人理解笔记
Jms即java消息服务javamessage service,所谓的面向消息编程,主要应用在企业内部各个系统之间做接口,以异步方式传递消息数据. Jms有2种传送模式,先来看第一种,即点对点传送模式 ...
- JMS学习三(ActiveMQ消息的可靠性)
下面我们来学习一下消息接受确认和发送持久化消息.消息的过期.消息的选择器和消息的优先级. 一.消息接收确认 1.jms消息只有在被确认之后才认为成功消费了这条消息.消息的成功消费通常包括三个步骤:(1 ...
- JMS学习之路(一):整合activeMQ到SpringMVC
JMS的全称是Java Message Service,即Java消息服务.它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息.把它应用到实际的业务需求中的话我们可以 ...
- JMS学习(四) Selector详解
一.前言 在掌握了消息的结构之后,我们接下来看一下JMS的一个重要功能:选择器.有些时候,作为消费者只希望处理自己感兴趣的消息.如果某个消息只有一个消费者,我们可以在让该客户端根据规则来处理自己感兴趣 ...
- JMS学习(二)- JMS Message Model 组成介绍及消息头详解
一.前言 从本文起依次详细介绍JMS中的一些重要的概念,主要参考了官方的JMS1.1的文档,该文档很老了,是02年的,那年,JAVA还没有被Oracle收购..本文主要介绍Message及其相关概念, ...
- JMS学习(一)基本概念
这两天面试了一两个公司,由于简历中的最近一个项目用到了JMS,然而面试官似乎对这个很感兴趣,所以都被问到了,但可惜的是,我除了说我们使用了JMS外,面对他们提出的一些关于JMS的问题,我回答得相当差, ...
- 消息队列-推/拉模式学习 & ActiveMQ及JMS学习
一种分类是推和拉 . 还有一种分类是 Queue 和 Pub/Sub . 先看的这一篇:http://blog.csdn.net/heyutao007/article/details/50131089 ...
随机推荐
- Erlang generic standard behaviours -- gen_server hibernate
hibernate 主要用于在内存空闲时,通过整理进程的stack,回收进程的heap 来达到回收内存节省资源的效果. hibernate 可用于OTP 进程以及普通进程, hibernate 的官方 ...
- GOF23设计模式之适配器模式(Adapter)
一.适配器模式概述 将一个类的接口转换成客户可用的另外一个接口. 将原本不兼容不能在一起工作的类添加适配处理类,使其可以在一起工作. 二.适配器模式场景 要想只有USB接口的电脑想使用PS/2接口的键 ...
- LogUtils日志管理工具
public class LogUtils { public static final int VERBOSE = 1; public static final int DEBUG = 2; publ ...
- bzoj1729: [Usaco2005 dec]Cow Patterns 牛的模式匹配
Description 约翰的N(1≤N≤100000)只奶牛中出现了K(1≤K≤25000)只爱惹麻烦的坏蛋.奶牛们按一定的顺序排队的时候,这些坏蛋总会站在一起.为了找出这些坏蛋,约翰让他的 ...
- IT诗词
年少太轻狂,误入IT行.白发森森立,两眼直茫茫.语言数十种,无一称擅长.三十而立时,无房单身郎. 年少不经事,埋头编程忙. 指键铿锵落,不及细思量. bug千百个,comment无一行. 休言敏捷易, ...
- Java测试用例简介
最近需要向组内其他成员普及一下关于Java测试用例的相关知识,特在此进行一下简单的学习和总结. JUnit简介 JUnit是一个开源的Java单元测试框架,JUnit4对原有的JUnit框架进行了大幅 ...
- CentOS7 系统菜单中添加快捷方式
一,在桌面新建一个文件 文件名随意,但必须带有.desktop的后缀名, 以Eclipse为例 vi /usr/share/applications/eclipse.desktop 二,在文件中写入如 ...
- JavaScript实现排序算法总结
<script type="text/javascript" src="js/laydate.js" > //插入排序 function inser ...
- Centos如何设置IP地址,LINUX怎么修改IP地址
对于很多刚刚接触linux的朋友来说,如何设置linux系统的IP地址,作为第一步,下面小编以centos系统为例,给大家演示如何给centos设置IP地址,如何修改linux 系统IP地址? 步骤阅 ...
- Flask之模板
2 了解Jinja2模板 知识点 模板使用 变量 过滤器 web表单 控制语句 宏.继承.包含 Flask中的特殊变量和方法 3.1 模板 在前面的示例中,视图函数的主要作用是生成请求的响应,这是最简 ...