1,引入jar
<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>${springframework}</version> </dependency>
2,代码解析
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" 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/jms http://www.springframework.org/schema/jms/spring-jms.xsd">
<!-- 连接工厂 -->
<bean id="activeMqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="failover:(tcp://192.168.81.86:51511,tcp://192.168.81.86:51512,tcp://192.168.81.86:51513)"/>
<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">
<property name="targetConnectionFactory" ref="activeMqConnectionFactory"/>
<property name="sessionCacheSize" value="100"/>
</bean>
<!-- 点对点队列 生产 网站提单bank-->
<bean id="bankReqQueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="vz.queue.service.trading"/>
</bean>
<!-- 生产者 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<!-- 默认发送的消息队列-->
<property name="defaultDestination" ref="bankReqQueueDestination"/>
<property name="receiveTimeout" value="10000" />
<property name="pubSubDomain" value="false"/>
</bean>
<!-- 点对点队列 消费 银行前置preBank-->
<bean id="preBankRespQueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="vz.queue.service.netweb.order.status"/>
</bean>
<!-- 点对点队列 消费 税局tax-->
<bean id="taxRespQueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="vz.queue.service.trading"/>
</bean>
<!-- 消费者 设置监听 银行前置preBank-->
<bean id="preBankQueueMessageListener" class="com.vzoom.bank.mq.finance.consumer.listener.PreBankQueueMessageListener"/>
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="preBankRespQueueDestination"/>
<property name="messageListener" ref="preBankQueueMessageListener"/>
<property name="sessionTransacted" value="true"/>
<!--<property name="concurrency" value="4-10"/>-->
<!-- 设置固定的线程数 -->
<property name="concurrentConsumers" value="6"></property>
<!-- 设置动态的线程数 -->
<property name="concurrency" value="2-9"></property>
<!-- 设置最大的线程数 -->
<property name="maxConcurrentConsumers" value="15"></property>
</bean>
<!-- 消费者 设置监听 税局tax-->
<bean id="taxQueueMessageListener" class="com.vzoom.bank.mq.finance.consumer.listener.TaxQueueMessageListener"/>
<bean id="jmsContainer1" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="taxRespQueueDestination"/>
<property name="messageListener" ref="taxQueueMessageListener"/>
<property name="sessionTransacted" value="true"/>
<!--<property name="concurrency" value="4-10"/>-->
<!-- 设置固定的线程数 -->
<property name="concurrentConsumers" value="6"></property>
<!-- 设置动态的线程数 -->
<property name="concurrency" value="2-9"></property>
<!-- 设置最大的线程数 -->
<property name="maxConcurrentConsumers" value="15"></property>
</bean>
</beans>
生产者:定制队列,默认队列发送
package com.vzoom.bank.mq.finance.producer.service;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
@Service
public class ProducerService {
@Resource(name="jmsTemplate")
private JmsTemplate jmsTemplate;
/**
* 向指定队列发送消息,定制队列
*/
public void sendMessage(Destination destination, final String msg) {
System.out.println("向队列" + destination.toString() + "发送了消息------------" + msg);
jmsTemplate.send(destination, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(msg);
}
});
}
/**
* 向默认队列发送消息,默认队列
*/
public void sendMessage(final String msg) {
String destination = jmsTemplate.getDefaultDestination().toString();
System.out.println("向队列" +destination+ "发送了消息------------" + msg);
jmsTemplate.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(msg);
}
});
}
}
消费者:主动消费(需要人为主动触发消费),监听消费(长连接,消息队列有消息立马自动消费)两种方式,监听消费需要在配置文件中配置相应监听器
主动消费
package com.vzoom.bank.mq.finance.consumer.service;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.TextMessage;
@Service
public class ConsumerService {
@Resource(name="jmsTemplate")
private JmsTemplate jmsTemplate;
/**
* 接收消息:区别于用监听的方式接收消息
*/
public TextMessage receive(Destination destination) {
TextMessage tm = (TextMessage) jmsTemplate.receive(destination);
try {
System.out.println("从队列" + destination.toString() + "收到了消息:\t"
+ tm.getText());
} catch (JMSException e) {
e.printStackTrace();
}
return tm;
}
}
监听消费1
package com.vzoom.bank.mq.finance.consumer.listener;
import org.apache.activemq.command.ActiveMQTextMessage;
import org.apache.xbean.spring.context.ClassPathXmlApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import javax.jms.*;
public class PreBankQueueMessageListener implements MessageListener {
/**
* 当收到消息后,自动调用该方法
* @param message
*/
@Override
public void onMessage(Message message) {
TextMessage tm = (TextMessage) message;
try {
System.out.println("PreBankQueueMessageListener监听到了文本消息:" + tm.getText());
//TODO
} catch (JMSException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
// 创建spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("common/ActiveMQ.xml");
// 从spring容器中获取JMSTemplate,这个对象是用于发送消息的
JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
//创建消息模式
Destination destination = (Destination)context.getBean("bankReqQueueDestination");
// 使用JMSTemplate发送消息
jmsTemplate.send(destination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
TextMessage textMessage = new ActiveMQTextMessage();
textMessage.setText("spring-queue的方式发送");
System.out.println("已发送消息...");
return textMessage;
}
});
}
}
监听消费2
package com.vzoom.bank.mq.finance.consumer.listener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class TaxQueueMessageListener implements MessageListener {
/**
* 当收到消息后,自动调用该方法
* @param message
*/
@Override
public void onMessage(Message message) {
TextMessage tm = (TextMessage) message;
try {
System.out.println("TaxQueueMessageListener监听到了文本消息:" + tm.getText());
//TODO
} catch (JMSException e){
e.printStackTrace();
}
}
}
测试
package com.vzoom.bank.controller;
import com.vzoom.bank.mq.finance.consumer.service.ConsumerService;
import com.vzoom.bank.mq.finance.producer.service.ProducerService;
import com.vzoom.domain.util.JsonBean;
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 javax.annotation.Resource;
import javax.jms.Destination;
@Controller
@RequestMapping(value = "/mq")
public class TestController {
@Autowired
ConsumerService consumerService;
@Autowired
ProducerService producerService;
@Resource(name="preBankRespQueueDestination")
private Destination receiveQueue;
@RequestMapping(value = "/sendMsg")
@ResponseBody
public String sendMsg(String msg){
try {
producerService.sendMessage(msg);
}catch (Exception e){
return JsonBean.toJsonString(JsonBean.EXCEPTION_ERROR,"失败");
}
return JsonBean.toJsonString(JsonBean.SUCCESS,"成功");
}
@RequestMapping(value = "/getMsg")
@ResponseBody
public Object getMsg(){
try {
consumerService.receive(receiveQueue);
}catch (Exception e){
return JsonBean.toJsonString(JsonBean.EXCEPTION_ERROR,"失败");
}
return JsonBean.toJsonString(JsonBean.SUCCESS,"成功");
}
}
结果
特别说明,以上点对点方式,监听器消费方式和主动消费方式只能选择一种,及配置了监听,那么主动消费就会失效,因为在消息产生的瞬间,消息就会被监听器监听到而被消费。