Spring整合ActiveMQ实现多个消费者配置(Queue与Topic模式)

需要依赖的jar包,包括但不限于
<!-- spring核心包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-oxm</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</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-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
    </dependency>
<!-- spring核心包 -->
<!-- activemq -->
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-all</artifactId>
        <version>5.11.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.xbean</groupId>
	<artifactId>xbean-spring</artifactId>
	<version>4.5</version>
    </dependency>
<!-- activemq -->

其中最后一个xbean-spring,如果没有依赖,则会在tomcat启动时报错。

spring配置相信大家都已经很熟悉了,在这里就不贴代码了,注意要加上下图代码,因为我把spring和activemq分开配置了。


activemq.xml

这个配置文件主要配置ActiveMQ的连接

<?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:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" 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.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
	http://activemq.apache.org/schema/core
    http://activemq.apache.org/schema/core/activemq-core.xsd
    http://www.springframework.org/schema/jms
    http://www.springframework.org/schema/jms/spring-jms.xsd">

    <!-- ActiveMQ的URL以及用户名,密码,因为是本地模式,所以是localhost,端口号修改参考https://blog.csdn.net/theshawshank/article/details/80476389-->  
    <amq:connectionFactory id="amqConnectionFactory"  
        brokerURL="tcp://localhost:61616" userName="admin" password="admin" />  
    <!-- Spring用于管理ConnectionFactory -->  
    <bean id="connectionFactory"  
        class="org.springframework.jms.connection.CachingConnectionFactory">   
        <property name="targetConnectionFactory" ref="amqConnectionFactory" />  
        <!-- 缓存数量 -->  
        <property name="sessionCacheSize" value="100" />  
    </bean>
    <!-- queue模板 -->
    <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
	<property name="connectionFactory" ref="connectionFactory" />
	<property name="defaultDestination" ref="queueDestination" />
	<property name="receiveTimeout" value="10000" />
	<!-- true是topic,false是queue,默认是false,此处显示写出false -->
	<property name="pubSubDomain" value="false" />
    </bean>
    <!-- topic模板 -->
    <bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
	<property name="connectionFactory" ref="connectionFactory" />
	<property name="defaultDestination" ref="topicDestination" />
	<property name="pubSubDomain" value="true" />
	<!-- 设置接收超时时间 60秒 <property name="receiveTimeout" value="60000"/> -->
	<!-- 消息不持久化 -->
	<property name="explicitQosEnabled" value="true"></property>
    </bean>
    <!-- 点对点 -->  
    <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">  
        <constructor-arg>  
            <value>queue</value>  
        </constructor-arg>  
    </bean>  
    <!-- 发布订阅 -->  
    <bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">  
        <constructor-arg>  
            <value>topic</value>  
        </constructor-arg>  
    </bean>  
</beans>

activemq-listener

该配置文件主要配置消费者

<?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:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" 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.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
	http://activemq.apache.org/schema/core
    http://activemq.apache.org/schema/core/activemq-core.xsd
    http://www.springframework.org/schema/jms
    http://www.springframework.org/schema/jms/spring-jms.xsd">
    <!-- 消息监听器 -->  
    <bean id="queueReceiver1"  
        class="xxxxxx.listener.QueueMessageListener1"></bean>  
    <bean id="queueReceiver2"  
        class="xxxxxx.listener.QueueMessageListener2"></bean>  
    <bean id="topicReceiver1"  
        class="xxxxxx.listener.TopicMessageListener1"></bean>  
    <bean id="topicReceiver2"  
        class="xxxxxx.listener.TopicMessageListener2"></bean>  
    <!-- Queue监听器 -->  
    <jms:listener-container destination-type="queue"  
        container-type="default" connection-factory="connectionFactory"  
        acknowledge="auto">  
        <jms:listener destination="queue" ref="queueReceiver1" />  
        <jms:listener destination="queue" ref="queueReceiver2" />  
    </jms:listener-container>  
    <!-- Topic监听器 -->  
    <jms:listener-container destination-type="topic"  
        container-type="default" connection-factory="connectionFactory"  
        acknowledge="auto">  
        <jms:listener destination="topic" ref="topicReceiver1" />  
        <jms:listener destination="topic" ref="topicReceiver2" />  
    </jms:listener-container>  
</beans>
点对点生产者代码
@Service
public class QueueProducerService {
    @Resource(name="jmsQueueTemplate")
    private JmsTemplate jmsQueueTemplate;

    public void sendMessage(Destination destination,final String msg){
        System.out.println(Thread.currentThread().getName()+" 向"+destination.toString()+"发送消息:"+msg);
        jmsQueueTemplate.send(destination, new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(msg);
            }
        });
    }

    public void sendMessage(final String msg){
        String destination = jmsQueueTemplate.getDefaultDestinationName();
        System.out.println(Thread.currentThread().getName()+" 向"+destination+"发送消息:"+msg);
        jmsQueueTemplate.send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(msg);
            }
        });
    }
}
发布订阅生产者代码
@Service
public class TopicProducerService {
    @Resource(name = "jmsTopicTemplate")
    private JmsTemplate jmsTopicTemplate;

    public void sendMessage(Destination destination, final String message) {
        System.out.println(Thread.currentThread().getName() + " 向" + destination.toString()
                + "发送主题:" + message);
        jmsTopicTemplate.send(destination, new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(message);
            }
        });
    }

    public void sendMessage(final String msg) {
        String destination = jmsTopicTemplate.getDefaultDestinationName();
        System.out.println(Thread.currentThread().getName() + " 向" + destination + "发送主题:" + msg);
        jmsTopicTemplate.send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(msg);
            }
        });
    }
}
消费者代码
public class QueueMessageListener1 implements MessageListener{
    @Override
    public void onMessage(Message message) {
    TextMessage tm = (TextMessage) message;
    try {
        System.out.println("QueueMessageListener1监听到了文本消息:\t"+ tm.getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

将上述代码复制四份,两个点对点,两个发布订阅,对应activemq-listener中配置的四个消费者。

单元测试代码

@RunWith(SpringJUnit4ClassRunner.class) // 表示继承了SpringJUnit4ClassRunner类
@ContextConfiguration(locations = { "classpath:spring-context.xml" })
@WebAppConfiguration
public class TestMQ {
    @Resource  
    private QueueProducerService queueSender;  
    @Resource  
    private TopicProducerService topicSender;  
    @Resource(name = "queueDestination")
	private Destination queueDestination;
	@Resource(name = "topicDestination")
	private Destination topicDestination;
  
    @Test  
    public void testSend() {  
        for (int i = 1; i < 6; i++) {  
            queueSender.sendMessage(queueDestination, "queue产生消息:" + i);  
        }  
          
        for (int i = 1; i < 6; i++) {  
            topicSender.sendMessage(topicDestination, "topic产生消息:" + i);  
        }  
    }
}

运行结果如下:


由运行结果可知,点对点模式的消息,只能被一个消费者接收;但是发布订阅模式的消息,可以被多个订阅者同时接收。

展开阅读全文

没有更多推荐了,返回首页