ActiveMQ
一、 ActiveMQ 简介
1 什么是 ActiveMQ
ActiveMQ 是 Apache 出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个
完全支持 JMS1.1 和 J2EE 1.4 规范的 JMS Provider 实现,尽管 JMS 规范出台已经是很久
的事情了,但是 JMS 在当今的 J2EE 应用中间仍然扮演着特殊的地位。
2 什么是消息
“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;
也可以更复杂,可能包含嵌入对象。
3 什么是队列
4 什么是消息队列
“消息队列”是在消息的传输过程中保存消息的容器。
5 常用消息服务应用
5.1ActiveMQ
ActiveMQ 是 Apache 出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持 JMS1.1 和 J2EE 1.4 规范的 JMS Provider 实现。
5.2RabbitMQ
RabbitMQ 是一个在 AMQP 基础上完成的,可复用的企业消息系统。他遵循 Mozilla Public License 开源协议。开发语言为 Erlang。
5.3RocketMQ
由阿里巴巴定义开发的一套消息队列应用服务。
二、消息服务的应用场景
消息队列的主要特点是异步处理,主要目的是减少请求响应时间和解耦。所以主要的使用场景就是将比较耗时而且**不需要即时(同步)**返回结果的操作作为消息放入消息队列。同时由于使用了消息队列,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,即解耦和。
5.1异步处理
5.1.1 用户注册
用户注册流程:
1)注册处理以及写数据库
2)发送注册成功的手机短信
3)发送注册成功的邮件信息
如果用消息中间件:则可以创建两个线程来做这些事情,直接发送消息给消息中间件,然后让邮件服务和短信服务自己去消息中间件里面去取消息,然后取到消息后再自己做对应的业务操作。就是这么方便
5.2应用的解耦
5.2.1 订单处理
生成订单流程:
1)在购物车中点击结算
2)完成支付
3)创建订单
4)调用库存系统
订单完成后,订单系统并不去直接调用库存系统,而是发送消息到消息中间件,写入一个订单信息。库存系统自己去消息中间件上去获取,然后做发货处理,并更新库存,这样能够实现互联网型应用追求的快这一个属性。而库存系统读取订单后库存应用这个操作也是非常快的,所以有消息中间件对解耦来说也是一个不错的方向。
5.3流量的削峰
5.3.1 秒杀功能
秒杀流程:
1)用户点击秒杀
2)发送请求到秒杀应用
3)在请求秒杀应用之前将请求放入到消息队列
4)秒杀应用从消息队列中获取请求并处理。
比如,系统举行秒杀活动,热门商品。流量蜂拥而至 100 件商品,10 万人挤进来怎么办?10 万秒杀的操作,放入消息队列。秒杀应用处理消息队列中的 10 万个请求中的前 100个,其他的打回,通知失败。流量峰值控制在消息队列处,秒杀应用不会瞬间被怼死.
三、 JMS
1 什么是 JMS
JMS(Java Messaging Service)是 Java 平台上有关面向消息中间件的技术规范,它便于消息系统中的 Java 应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口,简化企业应用的开发。
2 JMS 模型
2.1点对点模型(Point To Point)
生产者发送一条消息到 queue,只有一个消费者能收到。
2.2发布订阅模型(Publish/Subscribe)
发布者发送到 topic 的消息,只有订阅了 topic 的订阅者才会收到消息。
四、ActiveMQ 安装
1 下载资源
ActiveMQ 官网: http://activemq.apache.org
1.1版本说明
ActiveMQ5.10.x 以上版本必须使用 JDK1.8 才能正常使用。
ActiveMQ5.9.x 及以下版本使用 JDK1.7 即可正常使用。
2 上传至 Linux 服务器
3 解压安装文件
tar -zxf apache-activemq-5.9.0-bin.tar.gz
4 检查权限
ls -al apache-activemq-5.9.0/bin
如果权限不足,则无法执行,需要修改文件权限:
chmod 755 activemq
5 复制应用至本地目录
cp -r apache-activemq-5.9.0 /usr/local/activemq -r
6 启动 ActiveMQ
/usr/local/activemq/bin/activemq start
7 测试 ActiveMQ
7.1检查进程
ps aux | grep activemq
见到下述内容即代表启动成功
7.2管理界面
使用浏览器访问 ActiveMQ 管理应用, 地址如下:
http://ip:8161/admin/
用户名: admin
密码: admin
ActiveMQ 使用的是 jetty 提供 HTTP 服务.启动稍慢,建议短暂等待再访问测试.见到如下界面代表服务启动成功
首先关闭防火墙:
如果service iptables stop
关闭防火墙,没有成功!
是因为centos7不能关闭防火墙!
所以,这里要使用
systemctl stop firewalld
,然后就可以访问了。
7.3修改访问端口
修改 ActiveMQ 配置文件: /usr/local/activemq/conf/jetty.xml
配置文件修改完毕,保存并重新启动 ActiveMQ 服务。
7.4修改用户名和密码
修改 conf/users.properties 配置文件.内容为: 用户名=密码
保存并重启 ActiveMQ 服务即可.
8 重启 ActiveMQ
/usr/local/activemq/bin/activemq restart
9 关闭 ActiveMQ
/usr/local/activemq/bin/activemq stop
10 配置文件 activemq.xml
配置文件中,配置的是 ActiveMQ 的核心配置信息. 是提供服务时使用的配置. 可以修改启动的访问端口. 即 java 编程中访问 ActiveMQ 的访问端口.
默认端口为 61616.
使用协议是: tcp 协议.
修改端口后, 保存并重启 ActiveMQ 服务即可.
11 ActiveMQ 目录介绍
从它的目录来说,还是很简单的:
- bin 存放的是脚本文件
- conf 存放的是基本配置文件
- data 存放的是日志文件
- docs 存放的是说明文档
- examples 存放的是简单的实例
- lib 存放的是 activemq 所需 jar 包
- webapps 用于存放项目的目录
五、 ActiveMQ 术语
1 Destination
目的地,JMS Provider(消息中间件)负责维护,用于对 Message 进行管理的对象。MessageProducer 需要指定 Destination 才能发送消息,MessageReceiver 需要指定 Destination才能接收消息。
2 Producer
消息生成者,负责发送 Message 到目的地。
3 Consumer | Receiver
消息消费者,负责从目的地中消费【处理|监听|订阅】Message。
4 Message
消息,消息封装一次通信的内容。
六、 ActiveMQ 应用
1 ActiveMQ 常用 API 简介
下述 API 都是接口类型,由定义在 javax.jms 包中. 是 JMS 标准接口定义.
1.1ConnectionFactory
链接工厂, 用于创建链接的工厂类型.
1.2Connection
链接. 用于建立访问 ActiveMQ 连接的类型, 由链接工厂创建.
1.3Session
会话, 一次持久有效有状态的访问. 由链接创建.
1.4Destination & Queue
目的地, 用于描述本次访问 ActiveMQ 的消息访问目的地. 即 ActiveMQ 服务中的具体队列. 由会话创建.interface Queue extends Destination
1.5MessageProducer
消息生成者, 在一次有效会话中, 用于发送消息给ActiveMQ 服务的工具. 由会话创建.
1.6MessageConsumer
消息消费者【消息订阅者,消息处理者】, 在一次有效会话中, 用于从 ActiveMQ 服务中获取消息的工具. 由会话创建.
1.7Message
消息, 通过消息生成者向 ActiveMQ 服务发送消息时使用的数据载体对象或消息消费者从 ActiveMQ 服务中获取消息时使用的数据载体对象. 是所有消息【文本消息,对象消息等】具体类型的顶级接口. 可以通过会话创建或通过会话从 ActiveMQ 服务中获取.
2 JMS-HelloWorld
2.1处理文本消息
2.1.1 创建消息生产者
2.1.1.1 创建工程
2.1.1.2 修改 POM 文件添加 ActiveMQ 坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>mq-producer</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-all -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.9.0</version>
</dependency>
</dependencies>
</project>
2.1.1.3 编写消息的生产者
package com.bjsxt;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.transport.stomp.JmsFrameTranslator;
import org.apache.activemq.transport.stomp.Stomp;
import javax.jms.*;
public class HelloWorldProducer {
/**
* 生产消息
*/
public void sendHelloWorldActiveMQ(String msgTest){
//定义链接工厂
ConnectionFactory connectionFactory = null;
//定义链接对象
Connection connection = null;
//定义会话
Session session = null;
//定义消息目的地
Destination destination = null;
//定义消息的发送者
MessageProducer producer = null;
//定义消息
Message message = null;
try {
/**
* userName: userName:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* password:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* brokerURL:访问 ActiveMQ 服务的路径地址。
* 路径结构为:协议名://主机地址:端口号
*/
connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://192.168.70.151:61616");
//创建连接对象
connection = connectionFactory.createConnection();
//启动连接
connection.start();
/**
* transacted:是否使用事务 可选值为:true|false
* true:使用事务 当设置次变量值。Session.SESSION_TRANSACTED
* false:不适用事务,设置次变量则 acknowledgeMode 参数必须设置
* acknowledgeMode:
* Session.AUTO_ACKNOWLEDGE:自动消息确认机制
* Session.CLIENT_ACKNOWLEDGE:客户端确认机制
* Session.DUPS_OK_ACKNOWLEDGE:有副本的客户端确认消息机制
*/
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//创建目的地,目的地名称即队列的名称。消息的消费者需要通过此名称访问对应的队列
destination = session.createQueue("helloworld-destination");
//创建消息的生产者
producer = session.createProducer(destination);
//创建消息对象
message = session.createTextMessage(msgTest);
//发送消息
producer.send(message);
}catch (Exception e){
e.printStackTrace();
}finally {
//回收消息发送者资源
if (producer != null) {
try {
producer.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (connection == null) {
try {
connection.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2.1.2 创建消息消费者
2.1.2.1 创建工程
2.1.2.2 修改 POM 文件添加 ActiveMQ 坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>mq-consumer</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-all -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.9.0</version>
</dependency>
</dependencies>
</project>
2.1.2.3 编写消息的消费者
package com.bjsxt;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class HelloWorldConsumer {
/**
* 消费消息
*/
public void readHelloWorldActiveMQ(){
//定义链接工厂
ConnectionFactory connectionFactory = null;
//定义链接对象
Connection connection = null;
//定义会话
Session session = null;
//定义消息目的地
Destination destination = null;
//定义消息的消费者
MessageConsumer consumer = null;
//定义消息
Message message = null;
try {
/**
* userName: userName:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* password:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* brokerURL:访问 ActiveMQ 服务的路径地址。
* 路径结构为:协议名://主机地址:端口号
*/
connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://192.168.70.151:61616");
//创建连接对象
connection = connectionFactory.createConnection();
//启动连接
connection.start();
/**
* transacted:是否使用事务 可选值为:true|false
* true:使用事务 当设置次变量值。Session.SESSION_TRANSACTED
* false:不适用事务,设置次变量则 acknowledgeMode 参数必须设置
* acknowledgeMode:
* Session.AUTO_ACKNOWLEDGE:自动消息确认机制
* Session.CLIENT_ACKNOWLEDGE:客户端确认机制
* Session.DUPS_OK_ACKNOWLEDGE:有副本的客户端确认消息机制
*/
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//创建目的地,目的地名称即队列的名称。消息的消费者需要通过此名称访问对应的队列
destination = session.createQueue("helloworld-destination");
//创建消息的消费者
consumer = session.createConsumer(destination);
//创建消息对象
message = consumer.receive();
//处理消息
String msg = ((TextMessage)message).getText();
System.out.println("从 ActiveMQ 服务中获取\n" +
"的文本信息"+msg);
}catch (Exception e){
e.printStackTrace();
}finally {
//回收消息发送者资源
if (consumer != null) {
try {
consumer.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (connection == null) {
try {
connection.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2.1.3 测试
2.1.3.1 Producer
public class Test {
public static void main(String[] args) {
HelloWorldProducer producer = new HelloWorldProducer();
producer.sendHelloWorldActiveMQ("HelloWorld");
}
}
2.1.3.2 Consumer
public class Test {
public static void main(String[] args) {
HelloWorldConsumer consumer = new HelloWorldConsumer();
consumer.readHelloWorldActiveMQ();
}
}
2.2处理对象消息
2.2.1 定义消息对象
public class Users implements Serializable {
private int userid;
private String username;
private int userage;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getUserage() {
return userage;
}
public void setUserage(int userage) {
this.userage = userage;
}
@Override
public String toString() {
return "Users{" +
"userid=" + userid +
", username='" + username + '\'' +
", userage=" + userage +
'}';
}
}
2.2.2 创建生产者
public class HelloWorldProducer2 {
/**
* 生产消息
*/
public void sendHelloWorldActiveMQ(Users users){
//定义链接工厂
ConnectionFactory connectionFactory = null;
//定义链接对象
Connection connection = null;
//定义会话
Session session = null;
//目的地
Destination destination = null;
//定义消息的发送者
MessageProducer producer = null;
//定义消息
Message message = null;
try {
/**
* userName: userName:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* password:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* brokerURL:访问 ActiveMQ 服务的路径地址。
* 路径结构为:协议名://主机地址:端口号
*/
connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://192.168.70.151:61616");
//创建连接对象
connection = connectionFactory.createConnection();
//启动连接
connection.start();
/**
* transacted:是否使用事务 可选值为:true|false
* true:使用事务 当设置次变量值。Session.SESSION_TRANSACTED
* false:不适用事务,设置次变量则 acknowledgeMode 参数必须设置
* acknowledgeMode:
* Session.AUTO_ACKNOWLEDGE:自动消息确认机制
* Session.CLIENT_ACKNOWLEDGE:客户端确认机制
* Session.DUPS_OK_ACKNOWLEDGE:有副本的客户端确认消息机制
*/
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//创建目的地,目的地名称即队列的名称。消息的消费者需要通过此名称访问对应的队列
destination = session.createQueue("my-users");
//创建消息的生产者
producer = session.createProducer(destination);
//创建消息对象
message = session.createObjectMessage(users);
//发送消息
producer.send(message);
}catch (Exception e){
e.printStackTrace();
}finally {
//回收消息发送者资源
if (producer != null) {
try {
producer.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (connection == null) {
try {
connection.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2.2.3 定义消息消费者
public class HelloWorldConsumer2 {
/**
* 消费消息
*/
public void readHelloWorldActiveMQ(){
//定义链接工厂
ConnectionFactory connectionFactory = null;
//定义链接对象
Connection connection = null;
//定义会话
Session session = null;
//定义消息目的地
Destination destination = null;
//定义消息的消费者
MessageConsumer consumer = null;
//定义消息
Message message = null;
try {
/**
* userName: userName:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* password:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* brokerURL:访问 ActiveMQ 服务的路径地址。
* 路径结构为:协议名://主机地址:端口号
*/
connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://192.168.70.151:61616");
//创建连接对象
connection = connectionFactory.createConnection();
//启动连接
connection.start();
/**
* transacted:是否使用事务 可选值为:true|false
* true:使用事务 当设置次变量值。Session.SESSION_TRANSACTED
* false:不适用事务,设置次变量则 acknowledgeMode 参数必须设置
* acknowledgeMode:
* Session.AUTO_ACKNOWLEDGE:自动消息确认机制
* Session.CLIENT_ACKNOWLEDGE:客户端确认机制
* Session.DUPS_OK_ACKNOWLEDGE:有副本的客户端确认消息机制
*/
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//创建目的地,目的地名称即队列的名称。消息的消费者需要通过此名称访问对应的队列
destination = session.createQueue("my-users");
//创建消息的消费者
consumer = session.createConsumer(destination);
//创建消息对象
message = consumer.receive();
//处理消息
ObjectMessage objMessage = (ObjectMessage)message;
Users users = (Users)objMessage.getObject();
System.out.println(users);
}catch (Exception e){
e.printStackTrace();
}finally {
//回收消息发送者资源
if (consumer != null) {
try {
consumer.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (connection == null) {
try {
connection.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
producer,Test
public class Test {
public static void main(String[] args) {
/* HelloWorldProducer producer = new HelloWorldProducer();
producer.sendHelloWorldActiveMQ("HelloWorld");*/
Users users = new Users();
users.setUserid(1);
users.setUserage(20);
users.setUsername("zhangsan");
HelloWorldProducer2 producer2 = new HelloWorldProducer2();
producer2.sendHelloWorldActiveMQ(users);
}
}
Consumer,Test
public class Test {
public static void main(String[] args) {
/* HelloWorldConsumer consumer = new HelloWorldConsumer();
consumer.readHelloWorldActiveMQ();*/
HelloWorldConsumer2 consumer2 = new HelloWorldConsumer2();
consumer2.readHelloWorldActiveMQ();
}
}
3 JMS - 实现队列服务监听
队列服务监听使用的观察者设计模式
3.1创建消息生产者
public class HelloWorldProducer3 {
/**
* 生产消息
*/
public void sendHelloWorldActiveMQ(Users users){
//定义链接工厂
ConnectionFactory connectionFactory = null;
//定义链接对象
Connection connection = null;
//定义会话
Session session = null;
//目的地
Destination destination = null;
//定义消息的发送者
MessageProducer producer = null;
//定义消息
Message message = null;
try {
/**
* userName: userName:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* password:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* brokerURL:访问 ActiveMQ 服务的路径地址。
* 路径结构为:协议名://主机地址:端口号
*/
connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://192.168.70.151:61616");
//创建连接对象
connection = connectionFactory.createConnection();
//启动连接
connection.start();
/**
* transacted:是否使用事务 可选值为:true|false
* true:使用事务 当设置次变量值。Session.SESSION_TRANSACTED
* false:不适用事务,设置次变量则 acknowledgeMode 参数必须设置
* acknowledgeMode:
* Session.AUTO_ACKNOWLEDGE:自动消息确认机制
* Session.CLIENT_ACKNOWLEDGE:客户端确认机制
* Session.DUPS_OK_ACKNOWLEDGE:有副本的客户端确认消息机制
*/
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//创建目的地,目的地名称即队列的名称。消息的消费者需要通过此名称访问对应的队列
destination = session.createQueue("my-destination");
//创建消息的生产者
producer = session.createProducer(destination);
//创建消息对象
message = session.createTextMessage(msgTest);
//发送消息
producer.send(message);
}catch (Exception e){
e.printStackTrace();
}finally {
//回收消息发送者资源
if (producer != null) {
try {
producer.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (connection == null) {
try {
connection.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
3.2消息消费者
public class HelloWorldConsumer3 {
/**
* 消费消息
*/
public void readHelloWorldActiveMQ(){
//定义链接工厂
ConnectionFactory connectionFactory = null;
//定义链接对象
Connection connection = null;
//定义会话
Session session = null;
//定义消息目的地
Destination destination = null;
//定义消息的消费者
MessageConsumer consumer = null;
//定义消息
Message message = null;
try {
/**
* userName: userName:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* password:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* brokerURL:访问 ActiveMQ 服务的路径地址。
* 路径结构为:协议名://主机地址:端口号
*/
connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://192.168.70.151:61616");
//创建连接对象
connection = connectionFactory.createConnection();
//启动连接
connection.start();
/**
* transacted:是否使用事务 可选值为:true|false
* true:使用事务 当设置次变量值。Session.SESSION_TRANSACTED
* false:不适用事务,设置次变量则 acknowledgeMode 参数必须设置
* acknowledgeMode:
* Session.AUTO_ACKNOWLEDGE:自动消息确认机制
* Session.CLIENT_ACKNOWLEDGE:客户端确认机制
* Session.DUPS_OK_ACKNOWLEDGE:有副本的客户端确认消息机制
*/
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//创建目的地,目的地名称即队列的名称。消息的消费者需要通过此名称访问对应的队列
destination = session.createQueue("my-destination");
//创建消息的消费者
consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
//ActiveMQ 回调的方法。通过该方法将消息传递到 consumer
@Override
public void onMessage(Message message) {
//处理消息
String msg = null;
try {
msg = ((TextMessage)message).getText();
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println("从 ActiveMQ 服务中获取\n" +
"的文本信息"+msg);
}
});
}catch (Exception e){
e.printStackTrace();
}
}
}
consumer,Test
public class Test {
public static void main(String[] args) {
/* HelloWorldConsumer consumer = new HelloWorldConsumer();
consumer.readHelloWorldActiveMQ();*/
/*HelloWorldConsumer2 consumer2 = new HelloWorldConsumer2();
consumer2.readHelloWorldActiveMQ();*/
HelloWorldConsumer3 consumer3 = new HelloWorldConsumer3();
consumer3.readHelloWorldActiveMQ();
}
}
Producer,Test
public class Test {
public static void main(String[] args) {
/* HelloWorldProducer producer = new HelloWorldProducer();
producer.sendHelloWorldActiveMQ("HelloWorld");*/
/*Users users = new Users();
users.setUserid(1);
users.setUserage(20);
users.setUsername("zhangsan");
HelloWorldProducer2 producer2 = new HelloWorldProducer2();
producer2.sendHelloWorldActiveMQ(users);*/
HelloWorldProducer3 producer3 = new HelloWorldProducer3();
producer3.sendHelloWorldActiveMQ("Hello World");
}
}
4 Topic 模型
4.1Publish/Subscribe 处理模式(Topic)
消息生产者(发布)将消息发布到 topic 中,同时有多个消息消费者(订阅)消费该消息。
和点对点方式不同,发布到 topic 的消息会被所有订阅者消费。
当生产者发布消息,不管是否有消费者。都不会保存消息
一定要先有消息的消费者,后有消息的生产者。
4.2创建生产者
public class HelloWorldProducerTopic {
/**
* 生产消息
*/
public void sendHelloWorldActiveMQ(String msgTest){
//定义链接工厂
ConnectionFactory connectionFactory = null;
//定义链接对象
Connection connection = null;
//定义会话
Session session = null;
//定义消息目的地
Destination destination = null;
//定义消息的发送者
MessageProducer producer = null;
//定义消息
Message message = null;
try {
/**
* userName: userName:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* password:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* brokerURL:访问 ActiveMQ 服务的路径地址。
* 路径结构为:协议名://主机地址:端口号
*/
connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://192.168.70.151:61616");
//创建连接对象
connection = connectionFactory.createConnection();
//启动连接
connection.start();
/**
* transacted:是否使用事务 可选值为:true|false
* true:使用事务 当设置次变量值。Session.SESSION_TRANSACTED
* false:不适用事务,设置次变量则 acknowledgeMode 参数必须设置
* acknowledgeMode:
* Session.AUTO_ACKNOWLEDGE:自动消息确认机制
* Session.CLIENT_ACKNOWLEDGE:客户端确认机制
* Session.DUPS_OK_ACKNOWLEDGE:有副本的客户端确认消息机制
*/
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//创建目的地,目的地名称即队列的名称。消息的消费者需要通过此名称访问对应的队列
destination = session.createTopic("test-topic");
//创建消息的生产者
producer = session.createProducer(destination);
//创建消息对象
message = session.createTextMessage(msgTest);
//发送消息
producer.send(message);
}catch (Exception e){
e.printStackTrace();
}finally {
//回收消息发送者资源
if (producer != null) {
try {
producer.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (connection == null) {
try {
connection.close();
}catch (JMSException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
4.3创建消费者
为了测试效果,这里复制三份
public class HelloWorldConsumerTopic1 implements Runnable{
/**
* 消费消息
*/
public void readHelloWorldActiveMQ(){
//定义链接工厂
ConnectionFactory connectionFactory = null;
//定义链接对象
Connection connection = null;
//定义会话
Session session = null;
//定义消息目的地
Destination destination = null;
//定义消息的消费者
MessageConsumer consumer = null;
//定义消息
Message message = null;
try {
/**
* userName: userName:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* password:访问 ActiveMQ 服务的用户名。用户
* 密码。默认的为 admin。用户名可以通过
* jetty-ream.properties 文件进行修改
* brokerURL:访问 ActiveMQ 服务的路径地址。
* 路径结构为:协议名://主机地址:端口号
*/
connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://192.168.70.151:61616");
//创建连接对象
connection = connectionFactory.createConnection();
//启动连接
connection.start();
/**
* transacted:是否使用事务 可选值为:true|false
* true:使用事务 当设置次变量值。Session.SESSION_TRANSACTED
* false:不适用事务,设置次变量则 acknowledgeMode 参数必须设置
* acknowledgeMode:
* Session.AUTO_ACKNOWLEDGE:自动消息确认机制
* Session.CLIENT_ACKNOWLEDGE:客户端确认机制
* Session.DUPS_OK_ACKNOWLEDGE:有副本的客户端确认消息机制
*/
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//创建目的地,目的地名称即队列的名称。消息的消费者需要通过此名称访问对应的队列
destination = session.createTopic("test-topic");
//创建消息的消费者
consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
//ActiveMQ 回调的方法。通过该方法将消息传递到 consumer
@Override
public void onMessage(Message message) {
//处理消息
String msg = null;
try {
msg = ((TextMessage)message).getText();
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println("从 ActiveMQ 服务中获取---topic1\n" + "的文本信息"+msg);
}
});
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
this.readHelloWorldActiveMQ();
}
}
Consumer,,,,test
public class Test {
public static void main(String[] args) {
/* HelloWorldConsumer consumer = new HelloWorldConsumer();
consumer.readHelloWorldActiveMQ();*/
/*HelloWorldConsumer2 consumer2 = new HelloWorldConsumer2();
consumer2.readHelloWorldActiveMQ();*/
/*HelloWorldConsumer3 consumer3 = new HelloWorldConsumer3();
consumer3.readHelloWorldActiveMQ();*/
HelloWorldConsumerTopic1 topic1 = new HelloWorldConsumerTopic1();
Thread t1 = new Thread(topic1);
t1.start();
HelloWorldConsumerTopic2 topic2 = new HelloWorldConsumerTopic2();
Thread t2 = new Thread(topic2);
t2.start();
HelloWorldConsumerTopic3 topic3 = new HelloWorldConsumerTopic3();
Thread t3 = new Thread(topic3);
t3.start();
}
}
Producer,Test
public class Test {
public static void main(String[] args) {
/* HelloWorldProducer producer = new HelloWorldProducer();
producer.sendHelloWorldActiveMQ("HelloWorld");*/
/*Users users = new Users();
users.setUserid(1);
users.setUserage(20);
users.setUsername("zhangsan");
HelloWorldProducer2 producer2 = new HelloWorldProducer2();
producer2.sendHelloWorldActiveMQ(users);*/
/* HelloWorldProducer3 producer3 = new HelloWorldProducer3();
producer3.sendHelloWorldActiveMQ("Hello World");
*/
HelloWorldProducerTopic topic = new HelloWorldProducerTopic();
topic.sendHelloWorldActiveMQ("Hello Topic");
}
}
先运行消费者,再运行生产者
七、 Spring 整合 ActiveMQ
1 创建 spring-activemq-producer
1.1修改 POM 文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 对依赖的jar包的版本统一进行定义 -->
<properties>
<activemq.version>5.9.0</activemq.version>
<xbean.version>4.5</xbean.version>
<jms.version>4.1.6.RELEASE</jms.version>
<activemq-pool.version>5.9.0</activemq-pool.version>
<solrj.version>4.10.3</solrj.version>
<jedis.version>2.9.0</jedis.version>
<junit.version>4.12</junit.version>
<spring.version>4.1.3.RELEASE</spring.version>
<mybatis.version>3.2.8</mybatis.version>
<mybatis.spring.version>1.2.2</mybatis.spring.version>
<mysql.version>5.1.32</mysql.version>
<slf4j.version>1.6.4</slf4j.version>
<druid.version>1.0.9</druid.version>
<jstl.version>1.2</jstl.version>
<servlet-api.version>2.5</servlet-api.version>
<tomcat.version>2.2</tomcat.version>
<jsp-api.version>2.0</jsp-api.version>
<zkClient-version>0.10</zkClient-version>
<dubbo-version>2.5.4</dubbo-version>
<jackson.version>2.4.2</jackson.version>
<commons-net.version>3.3</commons-net.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
</properties>
<!-- jar包的依赖注入 ,由于该工程是一个父工程,所以jar包在该pom文件中只是声明 -->
<dependencyManagement>
<dependencies>
<!-- ActiveMQ客户端完整jar包依赖 -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>${activemq.version}</version>
</dependency>
<!-- ActiveMQ和Spring整合配置文件标签处理jar包依赖 -->
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>${xbean.version}</version>
</dependency>
<!-- Spring-JMS插件相关jar包依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${jms.version}</version>
</dependency>
<!-- Spring-JMS插件相关jar包依赖 -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>${activemq-pool.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jms-pool</artifactId>
<version>${activemq-pool.version}</version>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>${solrj.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>${commons-net.version}</version>
</dependency>
<!-- Jackson Json处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
<!-- tomcat插件,由于子项目不一定每个都是web项目,所以该插件只是声明,并未开启 -->
<pluginManagement>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>${tomcat.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bjsxt</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>spring-activemq-producer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- ActiveMQ客户端完整jar包依赖 -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
</dependency>
<!-- ActiveMQ和Spring整合配置文件标签处理jar包依赖 -->
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
</dependency>
<!-- Spring-JMS插件相关jar包依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jms-pool</artifactId>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<path>/</path>
<port>8080</port>
</configuration>
</plugin>
</plugins>
</build>
</project>
1.2整合 ActiveMQ
applicationContext-jms.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:amq="http://activemq.apache.org/schema/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 需要创建一个连接工厂,连接ActiveMQ. ActiveMQConnectionFactory. 需要依赖ActiveMQ提供的amq标签 -->
<!-- amq:connectionFactory 是bean标签的子标签, 会在spring容器中创建一个bean对象. 可以为对象命名.
类似: <bean id="" class="ActiveMQConnectionFactory"></bean> -->
<amq:connectionFactory brokerURL="tcp://192.168.70.151:61616"
userName="admin" password="admin" id="amqConnectionFactory" />
<!-- 配置池化的ConnectionFactory。 为连接ActiveMQ的connectionFactory提供连接池 -->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactoryBean">
<property name="connectionFactory" ref="amqConnectionFactory"></property>
<property name="maxConnections" value="10"></property>
</bean>
<!-- spring管理JMS相关代码的时候,必须依赖jms标签库. spring-jms提供的标签库. -->
<!-- 定义Spring-JMS中的连接工厂对象 CachingConnectionFactory - spring框架提供的连接工厂对象.
不能真正的访问MOM容器. 类似一个工厂的代理对象. 需要提供一个真实工厂,实现MOM容器的连接访问. -->
<!-- 配置有缓存的ConnectionFactory,session的缓存大小可定制。 -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
<property name="sessionCacheSize" value="3"></property>
</bean>
<!-- JmsTemplate配置 -->
<bean id="template" class="org.springframework.jms.core.JmsTemplate">
<!-- 给定连接工厂, 必须是spring创建的连接工厂. -->
<property name="connectionFactory" ref="connectionFactory"></property>
<!-- 可选 - 默认目的地命名 -->
<property name="defaultDestinationName" value="test-spring"></property>
</bean>
</beans>
applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:resource.properties"/>
<!-- 扫描bean对象 -->
<context:component-scan base-package="com.bjsxt.service"/>
</beans>
2 创建 spring-activemq-consumer
是一个 jar 工程
2.1修改 POM 文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bjsxt</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>spring-activemq-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- activemq客户端 -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
</dependency>
<!-- spring框架对JMS标准的支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<!-- ActiveMQ和spring整合的插件 -->
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
</dependencies>
</project>
2.2整合 ActiveMQ
applicationContext-jms.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:amq="http://activemq.apache.org/schema/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- 需要创建一个连接工厂,连接ActiveMQ. ActiveMQConnectionFactory. 需要依赖ActiveMQ提供的amq标签 -->
<!-- amq:connectionFactory 是bean标签的子标签, 会在spring容器中创建一个bean对象.
可以为对象命名. 类似: <bean id="" class="ActiveMQConnectionFactory"></bean>
-->
<amq:connectionFactory brokerURL="tcp://192.168.70.151:61616"
userName="admin" password="admin" id="amqConnectionFactory"/>
<!-- spring管理JMS相关代码的时候,必须依赖jms标签库. spring-jms提供的标签库. -->
<!-- 定义Spring-JMS中的连接工厂对象
CachingConnectionFactory - spring框架提供的连接工厂对象. 不能真正的访问MOM容器.
类似一个工厂的代理对象. 需要提供一个真实工厂,实现MOM容器的连接访问.
-->
<bean id="connectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
<property name="sessionCacheSize" value="3"></property>
</bean>
<!-- 注册监听器 -->
<!-- 开始注册监听.
需要的参数有:
acknowledge - 消息确认机制
container-type - 容器类型 default|simple
simple:SimpleMessageListenerContainer最简单的消息监听器容器,只能处理固定数量的JMS会话,且不支持事务。
default:DefaultMessageListenerContainer是一个用于异步消息监听器容器 ,且支持事务
destination-type - 目的地类型. 使用队列作为目的地.
connection-factory - 连接工厂, spring-jms使用的连接工厂,必须是spring自主创建的
不能使用三方工具创建的工程. 如: ActiveMQConnectionFactory.
-->
<jms:listener-container acknowledge="auto" container-type="default"
destination-type="queue" connection-factory="connectionFactory" >
<!-- 在监听器容器中注册某监听器对象.
destination - 设置目的地命名
ref - 指定监听器对象
-->
<jms:listener destination="test-spring" ref="myListener"/>
</jms:listener-container>
</beans>
applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描bean对象 -->
<context:component-scan base-package="com.bjsxt.service,com.bjsxt.listener"/>
</beans>
3 测试整合
需求:
1)在 producer 中创建 Users 对象
2)将 Users 对象传递到 ActiveMQ 中
3)在 Consumer 中获取 Users 对象并在控制台打印
3.1Producer 发送消息
3.1.1 如果使用了连接池需要添加两个坐标
PooledConnectionFactoryBean
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jms-pool</artifactId>
<version>5.9.0</version>
</dependency>
3.1.2 发送消息
@Service
public class UserServiceImpl implements UserService {
@Autowired
private JmsTemplate jmsTemplate;
@Override
public void addUser(final Users user) {
//发送消息
this.jmsTemplate.send(new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
Message message = session.createObjectMessage(user);
return message;
}
});
}
}
3.2Consumer 接收消息
3.2.1 接收消息
/**
* 消息服务监听器
* @author Administrator
*
*/
@Component(value="myListener")
public class MyMessageListener implements MessageListener{
@Autowired
private UserService userService;
@Override
public void onMessage(Message message) {
//处理消息
ObjectMessage objMessage = (ObjectMessage)message;
Users user=null;
try {
user = (Users)objMessage.getObject();
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.userService.showUser(user);
}
}
练习项目源码:https://gitee.com/cutelili/active-mq/tree/master/
RabbitMQ