ActiveMQ与spring集成实现Queue模式

时间:2023-03-09 19:32:46
ActiveMQ与spring集成实现Queue模式

  ActiveMQ可以和spring很好的集成,下面我们来看看,如何做个集成的demo。

  (1)pom.xml引入相关jar

<!-- spring相关 begin -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.5.RELEASE</version>
</dependency>
<!-- spring相关 end -->
<!-- activeMQ相关 begin-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.11.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<!-- activeMQ相关 end-->

  (2)添加生产者配置activemq-sender.xml

<description>JMS发布者应用配置</description>

    <!-- CachingConnectionFactory 连接工厂 (有缓存功能)-->
<bean id="cachingConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<!-- Session缓存数量 -->
<property name="sessionCacheSize" value="20" />
<property name="targetConnectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- MQ地址 账户名 密码-->
<property name="brokerURL" value="tcp://192.168.56.129:61616" />
<property name="userName" value="parry" />
<property name="password" value="parry123" />
<!-- 是否异步发送 -->
<property name="useAsyncSend" value="true"/>
</bean>
</property>
</bean> <!-- 接收消息的目的地(一个主题)点对点队列 -->
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<!-- 设置消息主题的名字 -->
<constructor-arg index="0" value="messages" />
</bean> <!-- 接收配置JMS模版 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="cachingConnectionFactory" />
<property name="defaultDestination" ref="destination" />
<!-- value为true为发布/订阅模式; value为false为点对点模式-->
<property name="pubSubDomain" value="false"/>
</bean>

  (3)添加消费者配置activemq-consumer.xml

<description>JMS订阅者应用配置</description>
<!-- CachingConnectionFactory 连接工厂 (有缓存功能)-->
<bean id="cachingConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<!-- Session缓存数量 -->
<property name="sessionCacheSize" value="20" />
<property name="targetConnectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- MQ地址 账户名 密码-->
<property name="brokerURL" value="tcp://192.168.56.129:61616" />
<property name="userName" value="parry" />
<property name="password" value="parry123" />
<!-- 是否异步发送 -->
<property name="useAsyncSend" value="true"/>
</bean>
</property>
</bean> <!-- 接收消息的目的地(一个主题)点对点队列 -->
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<!-- 设置消息主题的名字 -->
<constructor-arg index="0" value="messages" />
</bean> <!-- 消费者配置 (自己定义) -->
<bean id="consumer" class="com.parry.MQ.funcion.Listener" /> <!-- 消息监听容器 -->
<bean id="myListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="cachingConnectionFactory" />
<property name="destination" ref="destination" />
<property name="messageListener" ref="consumer" />
<!-- 如果消息的接收速率,大于消息处理的速率时,可以采取线程池方式 -->
<property name="taskExecutor" ref="queueMessageExecutor"/>
<!-- 设置固定的线程数 -->
<property name="concurrentConsumers" value="30"/>
<!-- 设置动态的线程数 -->
<property name="concurrency" value="20-50"/>
<!-- 设置最大的线程数 -->
<property name="maxConcurrentConsumers" value="80"/>
</bean>
<bean id="queueMessageExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="30" />
<property name="maxPoolSize" value="80" />
<property name="daemon" value="true" />
<property name="keepAliveSeconds" value="120" />
</bean>

  (4)新建一个发送消息的方法

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;
/**
* 发送消息
* @author Administrator
*
*/
@Component
public class QueueSender { @Autowired
private JmsTemplate myJmsTemplate; /**
* 发送一条消息到指定的队列(目标)
*
* @param queueName
* 队列名称
* @param message
* 消息内容
*/
public void send(String queueName, final String message) {
myJmsTemplate.send(queueName, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(message);
}
});
}
}

  (5)添加监听器

package com.parry.MQ.funcion;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage; /**
* 接收者监听类
* @author Administrator
*
*/
public class Listener implements MessageListener { public void onMessage(Message message) {
// 业务处理
try {
TextMessage message2 = (TextMessage) message;
System.out.println("接收到信息:" + message2.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}

  (6)写个一请求测试一下

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.parry.MQ.funcion.QueueSender; @Controller
public class App { @Autowired
private QueueSender sender; @RequestMapping("test")
@ResponseBody
public String Test() { sender.send("messages", "你好,这是我的第一条消息!");
return "Hello world";
}
}

  (7)测试结果

  aaarticlea/png;base64,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" alt="" />

  在ActiveMQ的管理后台,我们也能看到我们的消息(这里我多测试了几次):

  aaarticlea/png;base64,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" alt="" />