这篇文章主要是简单介绍一下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. Slide-卡盘效果

    <div style="width:950px;height:705px;"> <div class="J_TWidget" data-wid ...

  2. TIS100入门向攻略

    前几天某QQ群有人推荐这个游戏,百度了下找到了贴吧下载,但是攻略好像没找到,B站到是有个入门视频介绍还满有用的. 入门的话强烈推荐先看完了解个大概 http://www.bilibili.com/vi ...

  3. iOS原生地图开发指南续——大头针与自定义标注

    iOS原生地图开发指南续——大头针与自定义标注 出自:http://www.sxt.cn/info-6042-u-7372.html 在上一篇博客中http://my.oschina.net/u/23 ...

  4. TypeError: matchExpr[type].exec is not a function

    遇到了这个问题,很久没找到答案,后来使用了万能的google,貌似也没找到答案. 详细描述下: 通过使用 $(".select")来选择jqeury对象,没问题. 通过$(&quo ...

  5. java解析json

    1:下载另外一个Java的小包就可以了: http://www.JSON.org/java/json_simple.zip 里面有源码和文档例题和编程的lib包:编程只需要json_simple.ja ...

  6. Mysql 插入部分字段问题

    1. 字段如果不设置auto_increment和default的值,是不允许插入表的. 2. insert into student(id, name) values("1", ...

  7. [转]mysql drop、truncate和delete比较

    一.drop table tb drop将表格直接删除,没有办法找回. 立刻释放磁盘空间 ,不管是 Innodb和MyISAM . 二.truncate (table) tb 该命令可以清空一个表里的 ...

  8. C#.net 中 修饰符 详解 (来自MSDN)

    自己理解的不够深刻,无奈基础较差!记上一笔,记忆深刻些,哈哈…… 1. 访问修饰符 public 同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员. private 只有同一 ...

  9. 多语言配置--LogisticsPlatform物流平台系统

    先看:LanguageProvider.cs   中几个主要方法 1.读取默认语言 附user.ini文件: 2.获取语言类型 附LanguageType.xml 3.读取语言资源 附:   看ILa ...

  10. glibc2.14 install from centos

    安装glibc2.14 Tar xf glibc-2.14.tar.gz Cd glibc-2.14 Mkdir build Cd build ../configure –prefix=/opt/gl ...