发布订阅模式由消息生产者发布一条消息,所有订阅者都可以消费消息,如果有多个订阅者,在spring配置时需要不同的clientid。
测试需要消息发布类与订阅者监听消息的类:
package activemq.publisher;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import javax.jms.Destination;
/**
* Created by Administrator on 2017-04-07.
*/
public class MessageSender2 {
private final JmsTemplate jmsTemplate;
private final Destination destination;
public MessageSender2(final JmsTemplate jmsTemplate, final Destination destination) {
this.jmsTemplate = jmsTemplate;
this.destination = destination;
}
@Scheduled(cron = "0 * * * * ?")
public void send() {
try {
jmsTemplate.setDefaultDestination(destination);
jmsTemplate.convertAndSend("message");
System.out.println("发送消息 : " + "message");
} catch (Exception e) {
e.printStackTrace();
}
}
}
package activemq.publisher;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/**
* Created by Administrator on 2017-04-07.
*/
public class JmsMessageListener2 implements MessageListener {
public void onMessage(Message message) {
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
try {
String text = textMessage.getText();
System.out.println("接收到消息: " + text);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
我是在同一个项目中测试,spring配置文件如下:
<?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: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://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd">
<bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="failover:(tcp://192.168.2.24:61616)?timeout=5000"/>
<property name="userName" value="admin" />
<property name="password" value="admin" />
<!-- 是否异步发送 -->
<property name="useAsyncSend" value="true" />
</bean>
</property>
</bean>
<!--这个是队列目的地,pub/sub的-->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="YQSH_COMMON_TOPIC_CHANNEL"/>
</bean>
<!-- Spring topicJmsTemplate -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsFactory" />
<property name="sessionTransacted" value="true" />
<property name="explicitQosEnabled" value="true" />
<property name="receiveTimeout" value="30000" />
<property name="defaultDestination" ref="topicDestination" />
<!--区别它采用的模式为false是p2p;true是订阅 -->
<property name="pubSubDomain" value="true" />
</bean>
<!-- Message Sender Definition -->
<bean id="messageSender" class="activemq.publisher.MessageSender2">
<constructor-arg index="0" ref="jmsTemplate" />
<constructor-arg index="1" ref="topicDestination" />
</bean>
<!-- 消息监听器 -->
<bean id="jmsMessageListener" class="activemq.publisher.JmsMessageListener2">
</bean>
<bean id="myConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<!-- Session缓存数量 -->
<property name="sessionCacheSize" value="10" />
<!-- 接收者ID -->
<property name="clientId" value="client_119" />
<property name="targetConnectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- MQ地址 -->
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
</property>
</bean>
<!-- 发送消息的目的地(一个主题) -->
<bean id="myDestination" class="org.apache.activemq.command.ActiveMQTopic">
<!-- 设置消息主题的名字 -->
<constructor-arg index="0" value="YQSH_COMMON_TOPIC_CHANNEL" />
</bean>
<!-- 消息监听容器 -->
<bean id="myListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="myConnectionFactory" />
<!-- 发布订阅模式 -->
<property name="pubSubDomain" value="true"/>
<!-- 消息持久化 -->
<property name="subscriptionDurable" value="true"/>
<property name="receiveTimeout" value="10000"/>
<!-- 接收者ID -->
<property name="clientId" value="client_119" />
<property name="durableSubscriptionName" value="client_119"/>
<property name="destination" ref="myDestination" />
<property name="messageListener" ref="jmsMessageListener" />
</bean>
<bean id="myConnectionFactory2"
class="org.springframework.jms.connection.CachingConnectionFactory">
<!-- Session缓存数量 -->
<property name="sessionCacheSize" value="10" />
<!-- 接收者ID -->
<property name="clientId" value="client_120" />
<property name="targetConnectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- MQ地址 -->
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
</property>
</bean>
<!-- 消息监听器 -->
<bean id="jmsMessageListener3" class="activemq.publisher.JmsMessageListener">
</bean>
<!-- 消息监听容器 -->
<bean id="myListenerContainer2"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="myConnectionFactory2" />
<!-- 发布订阅模式 -->
<property name="pubSubDomain" value="true"/>
<!-- 消息持久化 -->
<property name="subscriptionDurable" value="true"/>
<property name="receiveTimeout" value="10000"/>
<!-- 接收者ID -->
<property name="clientId" value="client_120" />
<property name="durableSubscriptionName" value="client_120"/>
<property name="destination" ref="myDestination" />
<property name="messageListener" ref="jmsMessageListener3" />
</bean>
</beans>
启动项目后登录管理界面:
每发布一条消息入队,有两条消息出对。
上边spring配置了数据持久化,打开activemq安装目录下conf文件夹里activemq.xml文件,找到
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>
默认是以文件的方式持久化,文件在activemq安装目录下data文件夹下边kahadb文件夹里。