一、ActiveMQ的安裝
1.什么是ActiveMQ?
ActiveMQ 是 Apache 出品,最流行的,能力強勁的開源消息總線。ActiveMQ 是一個 完全支持 JMS1.1 和 J2EE 1.4 規范的 JMS Provider 實現,盡管 JMS 規范出臺已經是很久 的事情了,但是 JMS 在當今的 J2EE 應用中間仍然扮演著特殊的地位。
1.1什么是消息?
“消息”是在兩臺計算機間傳送的數據單位。消息可以非常簡單,例如只包含文本字符串; 也可以更復雜,可能包含嵌入對象。
1.2什么是隊列?
隊列的特點是先進先出。
- 什么是消息隊列?
“消息隊列”是在消息的傳輸過程中保存消息的容器。
1.3常用的消息服務應用:
(1)ActiveMQ
ActiveMQ 是 Apache 出品,最流行的,能力強勁的開源消息總線。ActiveMQ 是一個完 全支持 JMS1.1 和 J2EE 1.4 規范的 JMS Provider 實現。
(2)RabbitMQ
RabbitMQ 是一個在 AMQP 基礎上完成的,可復用的企業消息系統。他遵循 Mozilla Public License 開源協議。開發語言為 Erlang。
(3)RocketMQ
由阿里巴巴定義開發的一套消息隊列應用服務。
2.消息服務的應用場景:
消息隊列的主要特點是異步處理,主要目的是減少請求響應時間和解耦。所以主要的使 用場景就是將比較耗時而且不需要即時(同步)返回結果的操作作為消息放入消息隊列。同 時由于使用了消息隊列,只要保證消息格式不變,消息的發送方和接收方并不需要彼此聯系, 也不需要受對方的影響,即解耦和。
參考理解
- 異步處理:
用戶注冊流程:
(1)注冊處理以及寫數據庫
(2)發送注冊成功的手機短信
(3)發送注冊成功的郵件信息
如果用消息中間件:則可以創建兩個線程來做這些事情,直接發送消息給消息中間件, 然后讓郵件服務和短信服務自己去消息中間件里面去取消息,然后取到消息后再自己做對應 的業務操作。
- 訂單處理(解耦):
生成訂單流程:
(1)在購物車中點擊結算
(2)完成支付
(3)創建訂單
(4)調用庫存系統
訂單完成后,訂單系統并不去直接調用庫存系統,而是發送消息到消息中間件,寫入一 個訂單信息。庫存系統自己去消息中間件上去獲取,然后做發貨處理,并更新庫存,這樣能 夠實現互聯網型應用追求的快這一個屬性。而庫存系統讀取訂單后庫存應用這個操作也是非 常快的,所以有消息中間件對解耦來說也是一個不錯的方向。
- 秒殺功能 ( 流量的削峰 ):
秒殺流程:
(1)用戶點擊秒殺
(2)發送請求到秒殺應用
(3)在請求秒殺應用之前將請求放入到消息隊列
(4)秒殺應用從消息隊列中獲取請求并處理。
比如,系統舉行秒殺活動,熱門商品。流量蜂擁而至 100 件商品,10 萬人擠進來怎么 辦?10 萬秒殺的操作,放入消息隊列。秒殺應用處理消息隊列中的 10 萬個請求中的前 100 個,其他的打回,通知失敗。流量峰值控制在消息隊列處,秒殺應用不會瞬間被懟死。
3.JMS
3.1什么是JMS?
JMS(Java Messag Service)是 Java 平臺上有關面向消息中間件的技術規范,它便于 消息系統中的 Java 應用程序進行消息交換,并且通過提供標準的產生、發送、接收消息的接 口,簡化企業應用的開發。
3.2JMS 模型:
- 點對點模型(Point To Point):
生產者發送一條消息到 queue,只有一個消費者能收到。
- 發布訂閱模型(Publish/Subscribe) :
發布者發送到 topic 的消息,只有訂閱了 topic 的訂閱者才會收到消息。
4.安裝ActiveMQ:
4.1下載資源:
ActiveMQ 官網: http://activemq.apache.org ;
- 注意:
ActiveMQ5.10.x 以上版本必須使用 JDK1.8 才能正常使用。 ActiveMQ5.9.x 及以下版本使用 JDK1.7 即可正常使用。
4.2上傳并解壓:
將下載的資源上傳到Linux服務器并解壓;解壓命令“tar -zxf apache-activemq-5.9.0-bin.tar.gz ”;
將文件拷貝到指定目錄:“ cp apache-activemq-5.9.0 /usr/local/activemq -r ”;
4.3檢查權限:
ls -al apache-activemq-5.9.0/bin 如果權限不足,則無法執行,需要修改文件權限: chmod 755 activemq ;
- 啟動ActiveMQ:
/usr/local/activemq/bin/activemq start ;
- 檢查進程查看是否啟動成功:
ps aux | grep activemq ;下面表示啟動成功。
- 管理界面:
使用瀏覽器訪問 ActiveMQ 管理應用, 地址如下: http://ip:8161/admin/ ;用戶名:admin;密碼admin。
4.4修改訪問端口:
修改 ActiveMQ 配置文件: /usr/local/activemq/conf/jetty.xml ;
配置文件修改完畢,保存并重新啟動 ActiveMQ 服務。
- 修改用戶名和密碼:
修改 conf/users.properties 配置文件.內容為: 用戶名=密碼;
保存并重啟 ActiveMQ 服務即可。
- 重啟和關閉ActiveMQ:
/usr/local/activemq/bin/activemq restart ;
/usr/local/activemq/bin/activemq stop ;
- 配置文件activemq.xml :
配置文件中,配置的是 ActiveMQ 的核心配置信息. 是提供服務時使用的配置. 可以修改 啟動的訪問端口. 即 java 編程中訪問 ActiveMQ 的訪問端口. 默認端口為 61616;
使用協議是: tcp 協議;
修改端口后, 保存并重啟 ActiveMQ 服務即可。
4.5ActiveMQ目錄介紹:
(1)bin 存放的是腳本文件;
(2)conf 存放的是基本配置文件;
(3)data 存放的是日志文件;
(4)docs 存放的是說明文檔 ;
(5)examples 存放的是簡單的實例;
(6)lib 存放的是 activemq 所需 jar 包;
(7)webapps 用于存放項目的目錄 ;
5.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)ConnectionFactory:
鏈接工廠, 用于創建鏈接的工廠類型;
(2)Connection :
鏈接. 用于建立訪問 ActiveMQ 連接的類型, 由鏈接工廠創建。
(3)Session
會話, 一次持久有效有狀態的訪問. 由鏈接創建。
(4)Destination & Queue
目的地, 用于描述本次訪問 ActiveMQ 的消息訪問目的地. 即 ActiveMQ 服務中的具體隊 列. 由會話創建. interface Queue extends Destination
(5)MessageProducer
消息生成者, 在一次有效會話中, 用于發送消息給 ActiveMQ 服務的工具. 由會話創建。
(6)MessageConsumer
消息消費者【消息訂閱者,消息處理者】, 在一次有效會話中, 用于從 ActiveMQ 服務中 獲取消息的工具. 由會話創建。
(7)Message
消息, 通過消息生成者向 ActiveMQ 服務發送消息時使用的數據載體對象或消息消費者 從 ActiveMQ 服務中獲取消息時使用的數據載體對象. 是所有消息【文本消息,對象消息等】 具體類型的頂級接口. 可以通過會話創建或通過會話從 ActiveMQ 服務中獲取。
2.使用ActiveMQ處理文本消息:
2.1創建消息生產者:
- 修改POM文件添加ActiveMQ坐標:
<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>
2.2編寫消息的生產者:
/**
* 消息的生產者
*
* @author zhang
*
*/
public class HelloProducer {
public static void testProducer(String msg) {
// 定義工廠
ConnectionFactory factory = null;
// 定義連接對象
Connection conn = null;
// 定義會話
Session session = null;
// 目的地
Destination des = null;
// 定義消息發送者
MessageProducer producer = null;
// 定義消息
Message message = null;
try {
factory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.226.130:61616");
// 創建連接對象
conn = factory.createConnection();
// 啟動連接
conn.start();
/*
* transacted:是否使用事務 可選值為: true|false true:使用事務 當設置次變量 值。
* Session.SESSION_TRANSACTED false:不適用事務,設置次變量 則 acknowledgeMode 參數必須設置
* acknowledgeMode: Session.AUTO_ACKNOWLEDGE:自動消息確認機制
* Session.CLIENT_ACKNOWLEDGE:客戶端確認 機制 Session.DUPS_OK_ACKNOWLEDGE:有副本的客戶端確認消息機制
*/
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 創建目的地
des = session.createQueue("helloword-destination");
// 創建消息生產者
producer = session.createProducer(des);
// 創建消息對象
message = session.createTextMessage(msg);
// 發送消息
producer.send(message);
} catch (JMSException e) {
e.printStackTrace();
} finally {
// 關閉資源
if (producer != null) {
try {
producer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
2.3創建消息消費者
- 修改 POM 文件添加 ActiveMQ 坐標:
<!-- 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>
2.4編寫消息的消費者:
/**
* 消息的消費者
* @author zhang
*
*/
public class HelloConsumer {
public static void testConsumer() {
// 定義工廠
ConnectionFactory factory = null;
// 定義連接對象
Connection conn = null;
// 定義會話
Session session = null;
// 目的地
Destination des = null;
// 定義消息消費者
MessageConsumer consumer = null;
// 定義消息
Message message = null;
try {
factory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.226.130:61616");
// 創建連接對象
conn = factory.createConnection();
// 啟動連接
conn.start();
/*
* transacted:是否使用事務 可選值為: true|false true:使用事務 當設置次變量 值。
* Session.SESSION_TRANSACTED false:不適用事務,設置次變量 則 acknowledgeMode 參數必須設置
* acknowledgeMode: Session.AUTO_ACKNOWLEDGE:自動消息確認機制
* Session.CLIENT_ACKNOWLEDGE:客戶端確認 機制 Session.DUPS_OK_ACKNOWLEDGE:有副本的客戶端確認消息機制
*/
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 創建目的地
des = session.createQueue("helloword-destination");
// 創建消息生產者
consumer = session.createConsumer(des);
// 創建消息對象
message = consumer.receive();
//處理消息
String text = ((TextMessage)message).getText();
System.out.println("從ActiveMQ服務中獲取的文本信息"+text);
} catch (JMSException e) {
e.printStackTrace();
} finally {
// 關閉資源
if (consumer != null) {
try {
consumer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
}
3.處理對象消息:
3.1定義消費對象(生成getter和setter):
private int userid;
private String username;
private int userage;
3.2創建消息的生產者:
/**
* 消息的生產者
* @author zhang
*
*/
public class HelloProducer2 {
public static void testProducer(User user) {
// 定義工廠
ConnectionFactory factory = null;
// 定義連接對象
Connection conn = null;
// 定義會話
Session session = null;
// 目的地
Destination des = null;
// 定義消息發送者
MessageProducer producer = null;
// 定義消息
Message message = null;
try {
factory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.226.130:61616");
// 創建連接對象
conn = factory.createConnection();
// 啟動連接
conn.start();
/*
* transacted:是否使用事務 可選值為: true|false true:使用事務 當設置次變量 值。
* Session.SESSION_TRANSACTED false:不適用事務,設置次變量 則 acknowledgeMode 參數必須設置
* acknowledgeMode: Session.AUTO_ACKNOWLEDGE:自動消息確認機制
* Session.CLIENT_ACKNOWLEDGE:客戶端確認 機制 Session.DUPS_OK_ACKNOWLEDGE:有副本的客戶端確認消息機制
*/
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 創建目的地
des = session.createQueue("helloword-destination");
// 創建消息生產者
producer = session.createProducer(des);
// 創建消息對象
message = session.createObjectMessage(user);
// 發送消息
producer.send(message);
} catch (JMSException e) {
e.printStackTrace();
} finally {
// 關閉資源
if (producer != null) {
try {
producer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
}
3.2創建消息的消費者:
/**
* 消息的消費者
* @author zhang
*
*/
public class HelloConsumer2 {
public static void testConsumer() {
// 定義工廠
ConnectionFactory factory = null;
// 定義連接對象
Connection conn = null;
// 定義會話
Session session = null;
// 目的地
Destination des = null;
// 定義消息消費者
MessageConsumer consumer = null;
// 定義消息
Message message = null;
try {
factory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.226.130:61616");
// 創建連接對象
conn = factory.createConnection();
// 啟動連接
conn.start();
/*
* transacted:是否使用事務 可選值為: true|false true:使用事務 當設置次變量 值。
* Session.SESSION_TRANSACTED false:不適用事務,設置次變量 則 acknowledgeMode 參數必須設置
* acknowledgeMode: Session.AUTO_ACKNOWLEDGE:自動消息確認機制
* Session.CLIENT_ACKNOWLEDGE:客戶端確認 機制 Session.DUPS_OK_ACKNOWLEDGE:有副本的客戶端確認消息機制
*/
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 創建目的地
des = session.createQueue("helloword-destination");
// 創建消息生產者
consumer = session.createConsumer(des);
// 獲取消息對象
message = consumer.receive();
//處理消息
ObjectMessage objectMessage = (ObjectMessage)message;
User user = (User)objectMessage.getObject();
System.out.println("從ActiveMQ服務中獲取的文本信息"+user);
} catch (JMSException e) {
e.printStackTrace();
} finally {
// 關閉資源
if (consumer != null) {
try {
consumer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
}
-
實現:
示例
4.實現隊列服務監聽:
4.1創建消息生產者:
public class HelloProducer3 {
public static void testProducer(String msg) {
// 定義工廠
ConnectionFactory factory = null;
// 定義連接對象
Connection conn = null;
// 定義會話
Session session = null;
// 目的地
Destination des = null;
// 定義消息發送者
MessageProducer producer = null;
// 定義消息
Message message = null;
try {
factory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.226.130:61616");
// 創建連接對象
conn = factory.createConnection();
// 啟動連接
conn.start();
/*
* transacted:是否使用事務 可選值為: true|false true:使用事務 當設置次變量 值。
* Session.SESSION_TRANSACTED false:不適用事務,設置次變量 則 acknowledgeMode 參數必須設置
* acknowledgeMode: Session.AUTO_ACKNOWLEDGE:自動消息確認機制
* Session.CLIENT_ACKNOWLEDGE:客戶端確認 機制 Session.DUPS_OK_ACKNOWLEDGE:有副本的客戶端確認消息機制
*/
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 創建目的地
des = session.createQueue("02-message");
// 創建消息生產者
producer = session.createProducer(des);
// 創建消息對象
message = session.createTextMessage(msg);
// 發送消息
producer.send(message);
} catch (JMSException e) {
e.printStackTrace();
} finally {
// 關閉資源
if (producer != null) {
try {
producer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
}
4.2創建消息的消費者:
public class HelloConsumer3 {
public static void testConsumer() {
// 定義工廠
ConnectionFactory factory = null;
// 定義連接對象
Connection conn = null;
// 定義會話
Session session = null;
// 目的地
Destination des = null;
// 定義消息消費者
MessageConsumer consumer = null;
// 定義消息
Message message = null;
try {
factory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.226.130:61616");
// 創建連接對象
conn = factory.createConnection();
// 啟動連接
conn.start();
/*
* transacted:是否使用事務 可選值為: true|false true:使用事務 當設置次變量 值。
* Session.SESSION_TRANSACTED false:不適用事務,設置次變量 則 acknowledgeMode 參數必須設置
* acknowledgeMode: Session.AUTO_ACKNOWLEDGE:自動消息確認機制
* Session.CLIENT_ACKNOWLEDGE:客戶端確認 機制 Session.DUPS_OK_ACKNOWLEDGE:有副本的客戶端確認消息機制
*/
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 創建目的地
des = session.createQueue("02-message");
// 創建消息消費者
consumer = session.createConsumer(des);
// 創建消息消費者對象
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
System.out.println(message);
// 處理消息
String text = null;
try {
text = ((TextMessage) message).getText();
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println("從ActiveMQ服務中獲取的文本信息:" + text);
}
});
} catch (JMSException e) {
e.printStackTrace();
}
}
}
-
實現:
示例
5.Topic 模型 :
Publish/Subscribe 處理模式(Topic)
消息生產者(發布)將消息發布到 topic 中,同時有多個消息消費者(訂閱)消費該消 息。 和點對點方式不同,發布到 topic 的消息會被所有訂閱者消費。 當生產者發布消息,不管是否有消費者。都不會保存消息 一定要先有消息的消費者,后有消息的生產者。
5.1創建生產者:
public class HelloProducerTopic {
public static void testProducer(String msg) {
// 定義工廠
ConnectionFactory factory = null;
// 定義連接對象
Connection conn = null;
// 定義會話
Session session = null;
// 目的地
Destination des = null;
// 定義消息發送者
MessageProducer producer = null;
// 定義消息
Message message = null;
try {
factory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.226.130:61616");
// 創建連接對象
conn = factory.createConnection();
// 啟動連接
conn.start();
/*
* transacted:是否使用事務 可選值為: true|false true:使用事務 當設置次變量 值。
* Session.SESSION_TRANSACTED false:不適用事務,設置次變量 則 acknowledgeMode 參數必須設置
* acknowledgeMode: Session.AUTO_ACKNOWLEDGE:自動消息確認機制
* Session.CLIENT_ACKNOWLEDGE:客戶端確認 機制 Session.DUPS_OK_ACKNOWLEDGE:有副本的客戶端確認消息機制
*/
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 創建目的地
des = session.createTopic("topic");
// 創建消息生產者
producer = session.createProducer(des);
// 創建消息對象
message = session.createTextMessage(msg);
// 發送消息
producer.send(message);
} catch (JMSException e) {
e.printStackTrace();
} finally {
// 關閉資源
if (producer != null) {
try {
producer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (session != null) {
try {
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
}
- 創建消費者:
創建多個消費者;代碼相同;
public class HelloConsumerTopic implements Runnable{
public void testConsumer() {
// 定義工廠
ConnectionFactory factory = null;
// 定義連接對象
Connection conn = null;
// 定義會話
Session session = null;
// 目的地
Destination des = null;
// 定義消息消費者
MessageConsumer consumer = null;
// 定義消息
Message message = null;
try {
factory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.226.130:61616");
// 創建連接對象
conn = factory.createConnection();
// 啟動連接
conn.start();
/*
* transacted:是否使用事務 可選值為: true|false true:使用事務 當設置次變量 值。
* Session.SESSION_TRANSACTED false:不適用事務,設置次變量 則 acknowledgeMode 參數必須設置
* acknowledgeMode: Session.AUTO_ACKNOWLEDGE:自動消息確認機制
* Session.CLIENT_ACKNOWLEDGE:客戶端確認 機制 Session.DUPS_OK_ACKNOWLEDGE:有副本的客戶端確認消息機制
*/
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 創建目的地
des = session.createTopic("topic");
// 創建消息消費者
consumer = session.createConsumer(des);
// 創建消息消費者對象
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
System.out.println(message);
// 處理消息
String text = null;
try {
text = ((TextMessage) message).getText();
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println("從ActiveMQ服務中獲取的文本信息Topic1:" + text);
}
});
} catch (JMSException e) {
e.printStackTrace();
}
}
@Override
public void run() {
testConsumer();
}
}
6.測試:
6.1生產者測試:
public class Test {
public static void main(String[] args) {
// HelloProducer.testProducer("Hello");
// User user = new User();
// user.setUserid(01);
// user.setUsername("張三");
// user.setUserage(20);
// HelloProducer2.testProducer(user);
// HelloProducer3.testProducer("Dave");
HelloProducerTopic.testProducer("Dave");
}
}
-
實現效果:
先啟動消費者
6.2消費者測試:
public class Test {
public static void main(String[] args) {
// HelloConsumer.testConsumer();
// HelloConsumer2.testConsumer();
// HelloConsumer3.testConsumer();
HelloConsumerTopic topic1 = new HelloConsumerTopic();
Thread thread = new Thread(topic1);
thread.start();
HelloConsumerTopic2 topic2 = new HelloConsumerTopic2();
Thread thread2 = new Thread(topic2);
thread2.start();
HelloConsumerTopic3 topic3 = new HelloConsumerTopic3();
Thread thread3 = new Thread(topic3);
thread3.start();
}
}
三、spring整合ActiveMQ
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.zlw</groupId>
<artifactId>11-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.zlw</groupId>
<artifactId>11spring-actviemq-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.1整合項目:
- applicationContext-service.xml:
<!-- 掃描bean對象 -->
<context:component-scan base-package="com.zlw.service"/>
- springmvc:
<!-- 掃描@Controller -->
<context:component-scan base-package="com.zlw.web.controller"></context:component-scan>
<!-- 注冊兩個新對象 主要是為了來處理springmvc 中的其他 anntation 如:@requestmapping -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 視圖解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置靜態資源映射 -->
<mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>
<mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
- web.xml:
<!-- 上下文參數,告訴spring配置文件路徑 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置springmvc -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 整合ActiveMQ(applicationContext-jms):
<!-- 需要創建一個連接工廠,連接 ActiveMQ. ActiveMQConnectionFactory. 需要依賴 ActiveMQ 提供的 amq 標簽 -->
<!-- amq:connectionFactory 是 bean 標簽的子標簽, 會在 spring 容器中創建一個 bean 對象. 可以為對象命名.
類似: <bean id="" class="ActiveMQConnectionFactory"></bean> -->
<amq:connectionFactory
brokerURL="tcp://192.168.226.130:61616" userName="admin"
password="admin" id="amqConnectionFactory" />
<!-- spring 管理 JMS 相關代碼的時候,必須依賴 jms 標 簽庫. spring-jms 提供的標簽庫 -->
<!-- 定義 Spring-JMS 中的連接工廠對象 CachingConnectionFactory - spring 框架提供的 連接工廠對象.
不能真正的訪問 MOM 容器. 類似一個工廠的代理對象. 需要提供一個真實工 廠,實現 MOM 容器的連接訪問. -->
<bean id="pooledConnectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactoryBean">
<property name="connectionFactory" ref="amqConnectionFactory"></property>
<property name="maxConnections" value="10"></property>
</bean>
<!-- 配置有緩存的 ConnectionFactory,session 的 緩存大小可定制。 -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="pooledConnectionFactory"></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>
1.2定義對象:
private int userid;
private String username;
private String usermail;
private int userage;
1.3創建發送消息的service:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private JmsTemplate jmsTemplate;
@Override
public void addUser(Users user) {
// 發送消息
jmsTemplate.send(new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
Message message = session.createObjectMessage(user);
return message;
}
});
}
}
1.4創建Controller:
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("addUser")
public String userAdd(Users users) {
userService.addUser(users);
return "ok";
}
}
- 添加JSP頁面:
<body>
<form action="/user/addUser" method="post">
<p>
ID:<input type="text" name="userid" />
</p>
<p>
姓名:<input type="text" name="username" />
</p>
<p>
年齡:<input type="text" name="userage" />
</p>
<p>
郵箱:<input type="text" name="usermail" />
</p>
<p>
<input type="submit" value="提交" />
</p>
</form>
</body>
2.創建消費者項目:
2.1修改POM文件:
<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>
2.2創建接受消息的service:
@Service
public class UserServiceImpl implements UserService {
@Override
public void showUser(Users user) {
System.out.println(user);
}
}
2.3創建Listener處理消息:
@Component(value = "myListener")
public class MyMessageListener implements MessageListener{
@Autowired
private UserService userService;
@Override
public void onMessage(Message message) {
//處理消息
ObjectMessage objectMessage = (ObjectMessage)message;
Users user = null;
try {
user = (Users) objectMessage.getObject();
} catch (JMSException e) {
e.printStackTrace();
}
this.userService.showUser(user);
}
}
2.4測試:
public class Test {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext cpa = new ClassPathXmlApplicationContext(new String[] {"classpath:applicationContext-jms.xml","classpath:applicationContext-service.xml"});
cpa.start();
System.err.println("spring容器啟動!!!");
System.in.read();
}
}