今天接着上一篇文章实现发布订阅模式下消息的应答。
1.发布者:
ActiveMQ.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd">
<!--<amq:connectionFactory id="amqConnectionFactory"
brokerURL="tcp://192.168.1.218:61616" userName="" password="admin" /> -->
<bean id="amqConnectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://10.0.0.61:61616"></property>
<property name="userName" value="admin" />
<property name="password" value="admin" />
<!-- 是否异步发送 -->
<property name="useAsyncSend" value="true" />
</bean>
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
<!-- 同上,同理 -->
<!-- <constructor-arg ref="amqConnectionFactory" /> -->
<!-- Session缓存数量 -->
<property name="sessionCacheSize" value="100" />
</bean>
<!-- Spring JmsTemplate 的消息生产者 start-->
<!-- 定义JmsTemplate的Queue类型 -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<constructor-arg ref="connectionFactory" />
<!-- 非pub/sub模型(发布/订阅),即队列模式 -->
<property name="pubSubDomain" value="false" />
</bean>
<!-- 定义JmsTemplate的Topic类型 -->
<bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<constructor-arg ref="connectionFactory" />
<!-- pub/sub模型(发布/订阅) -->
<property name="pubSubDomain" value="true" />
</bean><!--Spring JmsTemplate 的消息生产者 end-->
<!-- 消息消费者 start-->
<!-- 定义Queue监听器 -->
<jms:listener-container destination-type="queue" container-type="default" connection-factory="connectionFactory" acknowledge="auto">
<jms:listener destination="replyQueue" ref="queueReceiver1"/>
</jms:listener-container>
<!-- 定义Topic监听器 -->
<jms:listener-container destination-type="topic" container-type="default" connection-factory="connectionFactory" acknowledge="auto">
<jms:listener destination="test.topic1" ref="topicReceiver1"/>
<jms:listener destination="test.topic1" ref="topicReceiver2"/>
</jms:listener-container>
<!-- 消息消费者 end -->
</beans>
其中,设置了一个名为replyQueue的队列和一个名为test.topic1的主题,含有两个主题消费者和一个队列接收者。
主题消费者1:
package com.tgb.SpringActivemq.mq.consumer.topic;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;
import com.tgb.model.User;
@Component
public class TopicReceiver1 implements MessageListener{
@Override
public void onMessage(Message message) {
// TODO Auto-generated method stub
User user;
try {
user = (User)((ObjectMessage) message).getObject();
System.out.println("TopicReceiver1接收到消息:"+user.getUserName()+ " _ " + user.getMobile()+"_"+user.getMobile1()+ " _ " + user.getUserName1());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
主题消费者2:
package com.tgb.SpringActivemq.mq.consumer.topic;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import org.springframework.stereotype.Component;
import com.tgb.model.User;
@Component
public class TopicReceiver2 implements MessageListener{
@Override
public void onMessage(Message message) {
// TODO Auto-generated method stub
User user;
try {
user = (User)((ObjectMessage) message).getObject();
System.out.println("TopicReceiver2接收到消息:"+user.getUserName()+" _ " + user.getMobile()+"_"+user.getMobile1()+ " _ " + user.getUserName1());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
队列接收者:
package com.tgb.SpringActivemq.mq.consumer.queue;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.TextMessage;
import org.springframework.stereotype.Component;
import com.tgb.model.User;
@Component("queueReceiver1")
public class QueueReceiver1 implements MessageListener{
@Override
public void onMessage(Message message) {
// TODO Auto-generated method stub
try {
String a = ((TextMessage) message).getText();
System.out.println("接收到消息:"+" _ " + a);
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.订阅者:
package com.satx.persistence;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
import com.tgb.model.User;
public class TopicReceiver {
public static void main(String[] args) {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ActiveMQConnectionFactory connectionFactory;
// Connection :JMS 客户端到JMS Provider 的连接
Connection connection = null;
// Session: 一个发送或接收消息的线程
final Session session;
// Destination :消息的目的地;消息发送给谁.
Destination destination;
// 消费者,消息接收者
// MessageConsumer 接口(消息消费者) 由会话创建的对象,用于接收发送到目标的消息。
// 消费者可以同步地(阻塞模式),或异步(非阻塞)接收队列和主题类型的消息。
MessageConsumer consumer;
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://10.0.0.61:61616");
try {
connectionFactory.setTrustAllPackages(true);
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
connection.setClientID("client_2");
// 启动
connection.start();
// 获取操作连接
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//queue_name跟sender的保持一致,一个创建一个来接收
Topic topic = session.createTopic("test.topic1");
consumer = session.createDurableSubscriber(topic, "client_2");
consumer.setMessageListener(
new MessageListener() {
@Override
public void onMessage(Message arg0) {
// TODO Auto-generated method stub
if(arg0 instanceof ObjectMessage){ //接收对象消息
ObjectMessage message = (ObjectMessage)arg0;
User user;
try {
user = (User)message.getObject();
System.out.println("收到"+user.getUserName() + " _ " + user.getMobile()+"_"+user.getMobile()+"_"+user.getMobile1());
Queue replyQueue = new ActiveMQQueue("replyQueue");
MessageProducer producer = session.createProducer(message.getJMSReplyTo());
producer.send(session.createTextMessage("回复成功"));
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
首先,查看未发送消息时各个消费者的状态:
是否收到回复消息:
最后,查看Activemq管理界面,消息已经成功接收。