ActiveMq(三) - 发布/订阅模式
1、概念
发布/订阅模式
发布/订阅模式允许一条消息可以被多个订阅了该Topic的消息消费者接收,当一个消息生产者产生一个消息时,会把消息放入一个Topic中,然后监听在此Topic上的消息消费者都能接收到消息。
对于发布/订阅模式,应该先启动消费者,监听在Topic上,然后等待生产者向Topic里添加消息。此处启动2个消费者
2、消费者代码
``` package com.activemq.pubsub;import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQTopic;
public class Consumers {
public static void main(String[] args) throws JMSException {
//通过tcp协议获取连接工厂
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://server01:61616");
//通过连接工厂获取连接
Connection connection = factory.createConnection();
connection.start();//开启连接
/**
* 创建session,此处有两个参数
* 第一个布尔类型的参数表示是否开启事务
* 第二个表示消息确认签收模式,此处为自动签收
*/
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建topic
Topic topic = new ActiveMQTopic("topic");
//创建消息消费者
MessageConsumer consumer1 = session.createConsumer(topic);
consumer1.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage)message;
try {
System.out.println("消费者一收到消息:" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
//创建消息消费者
MessageConsumer consumer2 = session.createConsumer(topic);
consumer2.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage)message;
try {
System.out.println("消费者二收到消息:" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
}
}
查看ActiveMq控制台Topics菜单页面,看到topic对应的消费者有2个,Messages Enqueued和Messages Dequeued都是0
![](https://images2018.cnblogs.com/blog/1373276/201804/1373276-20180415104635542-556711845.png)
<h1>3、生产者代码</h1>
此处生产者只发送一条消息
package com.activemq.pubsub;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQTopic;
public class Publisher {
public static void main(String[] args) throws JMSException {
//通过tcp协议获取连接工厂
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://server01:61616");
//通过连接工厂获取连接
Connection connection = factory.createConnection();
connection.start();//开启连接
/**
* 创建session,此处有两个参数
* 第一个布尔类型的参数表示是否开启事务
* 第二个表示消息确认签收模式,此处为自动签收
*/
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建topic
Topic topic = new ActiveMQTopic("topic");
//创建消息生产者
MessageProducer producer = session.createProducer(topic);
//创建消息对象
Message message = session.createTextMessage("topic消息");
//生产者发送消息
producer.send(message);
}
}
生产者启动之后,可以看到Eclipse控制台输入以下信息,表明两个消费者都收到生产者发送的这一条消息了。
消费者一收到消息:topic消息
消费者二收到消息:topic消息
再看看ActiveMq控制台,发现多了一个生产者Producer的Topic,Messages Enqueued为1,而topic对应的Messages Enqueued则变成1,Messages Dequeued 为2,也就是说,同一条消息被两个消息消费者接收到了。
![](https://images2018.cnblogs.com/blog/1373276/201804/1373276-20180415105042481-1840964775.png)