这篇文章主要是简单介绍一下JMS和ActiveMQ,以及使用ActiveMQ来写两个demo。

1. JMS是啥

百度百科的解释:

JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。

JMS只是接口,不同的提供商或者开源组织对其有不同的实现,ActiveMQ就是其中之一,它支持JMS,是Apache推出的。JMS中有几个对象模型:

连接工厂:ConnectionFactory 
JMS连接:Connection 
JMS会话:Session 
JMS目的:Destination 
JMS生产者:Producer 
JMS消费者:Consumer 
JMS消息两种类型:点对点和发布/订阅。

可以看出JMS实际上和JDBC有点类似,JDBC 是可以用来访问许多不同关系数据库的 API,而 JMS 则提供同样与厂商无关的访问方法,以访问消息收发服务。本文主要使用ActiveMQ。

2. ActiveMQ

关于ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。 
使用ActiveMQ首先需要去官网下载,我用的是apache-activemq-5.11.1,下载后解压缩,会看到里面有个activemq-all-5.11.1.jar,这个jar是接下来我们写程序的时候需要加进工程里的。 
在使用ActiveMQ之前,首先得先启动,刚才解压后的目录中有个bin目录,里面有win32和win64两个目录,根据自己电脑选择其中一个打开运行activemq.bat启动ActiveMQ。 
启动完成后,在浏览器中输入http://127.0.0.1:8161/admin/来访问ActiveMQ的服务器,用户名和密码是admin/admin。如下:

我们等会儿主要是看Queues和Topics这两个选项,因为这就是上面提到的点对点和发布/订阅的查看窗口。 
OK,准备工作做好了,下面开始针对这两中消息类型写两个demo来跑一下。

3. 点对点消息

首先写消息的生产者,也就是发送消息。

package org.shanheyongmu.cn.pointtopoint;
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.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; /**
* 消息的生产者,也就是发送消息
*/
public class JMSProducer { private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;//默认用户名
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;//默认密码
private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;//默认连接地址
private static final int SENDNUM=10;//定义消息发送数量 public static void main(String[] args) {
ConnectionFactory connectionFactory;//连接工厂,用来生产Connection
Connection connection=null;//连接
Session session;//会话,接收或者发送消息的线程
Destination destination;//消息的目的地
MessageProducer messageProducer;//消息发送者 //实例化 连接工厂
connectionFactory=new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEURL);
try{
connection=connectionFactory.createConnection();
connection.start();//启动连接
session=connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);//获取Session
destination=session.createQueue("FirstQueue1");//创建消息队列,名为FirstQueue1
messageProducer=session.createProducer(destination);//创建消息生产者
sendMessage(session,messageProducer);//发送消息
session.commit();//因为上面加了事务Boolean.TRUE表示有事务,所以commit
}catch(JMSException e){
e.printStackTrace();
} finally{
if(connection!=null){
try{
connection.close();
}catch(JMSException e){
e.printStackTrace();
}
}
}
}
/**
* 发送消息
* @param session
* @param messageProducer
* @throws JMSException
*/
private static void sendMessage(Session session,MessageProducer messageProducer) throws JMSException {
for(int i=0;i<JMSProducer.SENDNUM;i++){
TextMessage message=session.createTextMessage("ActiveMQ 发送的消息"+i);
messageProducer.send(message);
}
} }

可以看出,主要的流程就是上面提到的JMS的一些对象模型,这个和JDBC很类似,接下来再写消息的消费者,也就是接收方。

package org.shanheyongmu.cn.pointtopoint;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session; import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; public class JMSConsumer {
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;//默认用户名
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;//默认密码
private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;//默认连接地址 public static void main(String[] args) {
ConnectionFactory connectionFactory;//连接工厂,用来生产Connection
Connection connection=null;
Session session;//会话,接收或者发送消息的线程
Destination destination;//消息的目的地
MessageConsumer messageConsumer;//消息消费者
//实例化连接工厂
connectionFactory=new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEURL);
try{
connection=connectionFactory.createConnection();//通过连接工厂获取链接
connection.start();//启动连接
session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);//获取session 不需要加事务了
destination=session.createQueue("FirstQueue1");//创建消息队列,名为FirstQueue1
messageConsumer=session.createConsumer(destination);//创建消息消费者
//注册消息监听
messageConsumer.setMessageListener(new Listener());
}catch(Exception e){
e.printStackTrace();
}
} }

从代码中可以看出,接收消息需要一个监听器,这个监听器可以自己来实现,需要实现MessageListener接口,如下:

package org.shanheyongmu.cn.pointtopoint;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage; /**
* 接收消息需要个监听类
* */
public class Listener implements MessageListener { public void onMessage(Message message) {
try{
System.out.println("收到的消息: "+((TextMessage)message).getText());
}catch(JMSException e){
e.printStackTrace();
}
} }

ok,现在就可以运行这两个程序了,首先运行JMSProducer,然后运行JMSConsumer就可以看到控制台的消息输出。然后打开ActiveMQ的服务器,可以看到如下信息: 

可以看出,总共产生了20条消息,消费了20条消息,这就是点对点的模式。

4. 订阅/发布消息

下面写一个订阅/发布消息的demo。和上面点对点类似,不过代码有一些细节上的差异,另外订阅方用两个Consumer来模拟一下,发布方用一个Producer来模拟。

发布消息:

package org.shanheyongmu.cn.subscriber;

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.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; /**
* 发送消息
*/
public class JMSProducer { private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;//默认用户名
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;//默认密码
private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;//默认连接地址
private static final int SENDNUM=10;//定义消息发送数量 public static void main(String[] args) {
ConnectionFactory connectionFactory;//连接工厂,用来生产Connection
Connection connection=null;//会话
Session session;//会话,接收或者发送消息的线程
Destination destination;//消息的目的地
MessageProducer messageProducer;//消息发送者
//实例化连接工厂
connectionFactory=new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEURL);
try{
connection=connectionFactory.createConnection();//通过连接工厂获取连接
connection.start();//启动连接
session=connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);//获取session
destination=session.createTopic("FirstTopic");//创建消息队列 名为FirstTopic1
messageProducer=session.createProducer(destination);//创建消息生产者
sendMessage(session,messageProducer);//发送消息
session.commit();//因为上面加了事务Boolean.TRUE表示有事务,所以要commit
}catch(JMSException e){
e.printStackTrace();
}finally{
if(connection!=null){
try {
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
} /**
* 发布消息
* @param session
* @param messageProducer
* @throws JMSException
*/
private static void sendMessage(Session session,MessageProducer messageProducer) throws JMSException {
for(int i=0;i<JMSProducer.SENDNUM;i++){
TextMessage message=session.createTextMessage("ActiveMQ 发布的消息"+i);
System.out.println("ActiveMQ发布的消息"+i);
messageProducer.send(message); } }
}

和点对点有个细微的区别,这里是用session.createTopic,注意一下即可。 
订阅消息:

package org.shanheyongmu.cn.subscriber;

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.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.shanheyongmu.cn.pointtopoint.Listener; /**
*订阅消息
*/
public class JMSConsumer {
private static final String USERNAME=ActiveMQConnection.DEFAULT_USER;//默认用户名
private static final String PASSWROD=ActiveMQConnection.DEFAULT_PASSWORD;//默认密码
private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL;//默认连接地址 public static void main(String[] args) {
ConnectionFactory connectionFactory;//连接工厂,用来生产Connection
Connection connection=null;//连接
Session session;//会话,接收或者发送消息的线程
Destination destination;//消息的目的地
MessageConsumer messageConsumer;//消息消费者 //实例化连接工厂
connectionFactory=new ActiveMQConnectionFactory(USERNAME,PASSWROD,BROKEURL);
try{
connection=connectionFactory.createConnection();//通过连接工厂获取连接
connection.start();//启动连接
session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);//获取session 不需要加事务了
destination=session.createTopic("FirstTopic1");//创建消息队列,名为FirstTopic1
messageConsumer=session.createConsumer(destination);//创建消息消费者
//注册消息监听
messageConsumer.setMessageListener(new Listener());
}catch(JMSException e){
e.printStackTrace();
}
} }

同样地,这里也是使用createTopic,另一个订阅方的代码和这个一样,就不写了,然后运行所有的JMSConsumer,再运行JMSProducer,就会看到控制台会打印出消息。再看一下服务器上的状态: 
 
我们可以看到,有两个订阅者,发布了10条消息,消费了20条。以上就是ActiveMQ使用的简单demo。

【JMS】JMS之ActiveMQ的使用的更多相关文章

  1. 解决Maven中Missing artifact javax.jms:jms:jar:1.1:compile

    搭建好项目后报错: Missing artifact javax.jms:jms:jar:1.1:compile  于POM.xml中 解决方案: 一 :在nexus中配置一个代理仓库     地址为 ...

  2. maven 下载jar失败: Missing artifact javax.jms:jms:jar:1.1

    想从中央仓库下载, 却出现404, 原来,而中央仓库中都只有pom文件, 而没有jar包. 那就换一个 仓库吧: http://repository.jboss.com/maven2/: 终于找到了你 ...

  3. log4j的1.2.15版本,在pom.xml中的顶层project报错错误: Failure to transfer javax.jms:jms:jar:1.1 from https://maven-repository.dev.java.net/nonav/repository......

    在动态网站工程中,添加了Pom依赖,当添加log4j的1.2.15版本依赖时,在pom.xml中的顶层project报错错误: Failure to transfer javax.jms:jms:ja ...

  4. JMS消息中间件系列[ActiveMQ](一)

    版本5.13.3的特性: 1.Supports a variety of Cross Language Clients and Protocols from Java, C, C++, C#, Rub ...

  5. Spring整合JMS(一)——基于ActiveMQ实现

    1.1     JMS简介 JMS的全称是Java Message Service,即Java消息服务.它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息.把它应用到 ...

  6. 消息中间件系列一:入门、JMS规范、ActiveMQ使用

    一.入门 1. 消息中间件的定义 没有标准定义,一般认为,采用消息传送机制/消息队列 的中间件技术,进行数据交流,用在分布式系统的集成 2. 为什么要用消息中间件 解决分布式系统之间消息的传递.电商场 ...

  7. JMS学习以及jms的实现activeMq

    1.JMS规范介绍: http://www.cnblogs.com/hapjin/p/5431706.html http://elim.iteye.com/blog/1893038 http://bl ...

  8. JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系

    一,消息的持久化和非持久化 ①DeliveryMode 这是传输模式.ActiveMQ支持两种传输模式:持久传输和非持久传输(persistent and non-persistent deliver ...

  9. 实现JMS规范的ActiveMQ

    ActiveMQ是Apache软件基金会的开源产品,支持AMQP协议.MQTT协议(和XMPP协议作用类似).Openwire协议和Stomp协议等多种消息协议.并且ActiveMQ完整支持JMS A ...

  10. Spring整合JMS(一)——基于ActiveMQ实现 (转)

    *注:别人那复制来的 1.1     JMS简介 JMS的全称是Java Message Service,即Java消 息服务.它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者 ...

随机推荐

  1. Asp.net使用代码修改配置文件的节点值

    使用代码修改配置文件的方法: 1.打开配置文件写入的权限 2.先按节点名称长到要修改的节点,然后删除,紧接着将有新值的节点添加回去 3.关闭配置文件写入的权限 修改Appsetting节点的值,修改其 ...

  2. 代码规范、GitHub提交源码的标准 答题人-杨宇杰

    1.格式与命名规范1.1 缩进 使用Tab缩进,而不是空格键1.2 换行 每行120字符 if,for,while语句只有单句时,如果该句可能引起阅读混淆,需要用" {"和&quo ...

  3. zabbix中文乱码解决方法

    将windows下的字体文件Fonts\simkai.ttf上传到zabbix的WEB目录下的fonts目录下 修改zabbix的PHP配置 将原来的DejaVuSans更改成simkai vim / ...

  4. Android中Handler 、Thread和Runnable之间的关系

    在多线程编程的时候,我们经常会用到Handler,Thread和Runnable这三个类,我们来看看这三个类之间是怎么样的关系? 首先说明Android的CPU分配的最小单元是线程,Handler一般 ...

  5. 用CSS绘制箭头等三角形图案 [译]

    最近重新设计了我的网站,准备添加tooltips提示信息效果.实现很容易,但我想要让提示功能具有三角形的指示图标.当我重新思考想要所设计的每个图标颜色都随心所欲的时候,采用图片那就是一场灾难.幸运的是 ...

  6. PROC SORT

    PROC SORT DATA=输入数据集 <OUT=输出数据集><选项>; BY 关键变量; RUN; PROC SORT 语法如上,其中在尖括号中的可以不出现,也不会报错. ...

  7. Chrome: Resource interpreted as Font but transferred with MIME type font/x-woff

    最近,项目中加入了Bootstrap进行界面优化,但是,项目加载运行之后,控制台总是提示以下错误信息: GET http://localhost:8080/.../fonts/fontawesome- ...

  8. 8.4.4 Picasso

    Picasso 收到加载及显示图片的任务,创建 Request 并将它交给 Dispatcher,Dispatcher 分发任务到具体 RequestHandler,任务通过 MemoryCache ...

  9. SQL中的共享锁分析及如何解锁

    1.1.1 摘要 在系统设计过程中,系统的稳定性.响应速度和读写速度至关重要,就像12306.cn那样,当然我们可以通过提高系统并发能力来提高系统性能总体性能,但在并发作用下也会出现一些问题,例如死锁 ...

  10. Bootstrap CDN推荐

    Bootstrap CDN推荐 本站实例采用的是百度的静态资源库(http://cdn.code.baidu.com/)上的Bootstrap资源. 百度的静态资源库的 CDN 服务,访问速度更快.加 ...