Spring结合嵌入式ActiveMQ使用消息队列
来源:互联网 发布:php 命名空间 大小写 编辑:程序博客网 时间:2024/05/21 17:12
applicationContext.xml
<?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:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"xmlns:jpa="http://www.springframework.org/schema/data/jpa"xmlns:amq="http://activemq.apache.org/schema/core"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.2.xsdhttp://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsdhttp://www.springframework.org/schema/jmshttp://www.springframework.org/schema/jms/spring-jms-3.0.xsdhttp://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.1.0.xsd">......<!-- Embedded ActiveMQ Broker --><amq:broker id="broker" useJmx="false" persistent="false"><amq:transportConnectors><amq:transportConnector uri="tcp://localhost:61617" /></amq:transportConnectors></amq:broker><import resource="classpath:activemq-properties.xml" /><import resource="classpath:activemq-jms.xml" /></beans>这里引入了activemq-properties.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="jmsProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" name="jmsProperties"> <property name="order" value="99999" /> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="properties"> <value> <!-- JMS --> JMS.BROKER.URL=tcp://localhost:61617 JMS.QUEUE.NAME1=IN_QUEUE1 JMS.QUEUE.NAME2=IN_QUEUE2 </value> </property> </bean></beans>和activemq-jms.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- ActiveMQ connection factory --> <bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <constructor-arg index="0" value="${JMS.BROKER.URL}" /> </bean> <!-- ConnectionFactory Definition --> <bean id="connectionFactory1" class="org.springframework.jms.connection.CachingConnectionFactory"> <constructor-arg ref="amqConnectionFactory" /> <property name="sessionCacheSize" value="10"></property> </bean> <bean id="connectionFactory2" class="org.springframework.jms.connection.CachingConnectionFactory"> <constructor-arg ref="amqConnectionFactory" /> <property name="sessionCacheSize" value="10"></property> </bean> <!-- Destination Queue --> <bean id="destinationQueue1" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg index="0" value="${JMS.QUEUE.NAME1}" /> </bean> <bean id="destinationQueue2" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg index="0" value="${JMS.QUEUE.NAME2}" /> </bean> <!-- Message converter --> <bean id="messageConv" class="com.sap.c4c.wechat.jms.MessageConverter"><!--自定义的消息转换器--> </bean> <!-- JmsTemplate Definition --> <!--<bean id="jmsTemplate1" class="com.sap.c4c.wechat.jms.MessageJmsTemplate">--><!--自定义的消息JMS模板,但其实没有必要,可以像下面两个那样--> <!--<property name="connectionFactory" ref="connectionFactory1" />--> <!--<property name="defaultDestination" ref="destinationQueue1" />--> <!--<property name="messageConverter" ref="messageConv"></property>--> <!--</bean>--> <bean id="jmsTemplate1" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory1" /> <property name="defaultDestination" ref="destinationQueue1" /> <property name="messageConverter" ref="messageConv"></property> </bean> <bean id="jmsTemplate1_b" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory1" /> <property name="defaultDestination" ref="destinationQueue1" /> <property name="messageConverter" ref="messageConv"></property> </bean> <bean id="jmsTemplate2" class="com.sap.c4c.wechat.jms.MessageJmsTemplate"> <property name="connectionFactory" ref="connectionFactory2" /> <property name="defaultDestination" ref="destinationQueue2" /> <property name="messageConverter" ref="messageConv"></property> </bean> <!-- Message Producer --> <bean id="messageProducer1" class="com.sap.c4c.wechat.jms.MessageProducer1" ><!--第一种消息生产者--> <!--<property name="jmsTemplate">--><!--这里不定义,在类中定义--> <!--<list>--> <!--<ref bean="jmsTemplate_1" />--> <!--<ref bean="jmsTemplate_2" />--> <!--</list>--> <!--</property>--> </bean> <bean id="messageProducer2" class="com.sap.c4c.wechat.jms.MessageProducer2" /><!--第二种消息生产者--> <!-- Message Consumer --> <bean id="messageConsumer1" class="com.sap.c4c.wechat.jms.MessageConsumer1" /><!--第一种消息消费者--> <bean id="messageConsumer2" class="com.sap.c4c.wechat.jms.MessageConsumer2" /><!--第二种消息消费者--> <!-- Message Consumer Container --> <bean id="container1" class="org.springframework.jms.listener.DefaultMessageListenerContainer"><!--第一套消息传送--> <property name="connectionFactory" ref="connectionFactory1" /> <property name="destinationName" value="${JMS.QUEUE.NAME1}" /> <property name="messageListener" ref="messageConsumer1" /> </bean> <bean id="container2" class="org.springframework.jms.listener.DefaultMessageListenerContainer"><!--第二套消息传送,这里允许多个第二种消费者--> <property name="connectionFactory" ref="connectionFactory2" /> <property name="destinationName" value="${JMS.QUEUE.NAME2}" /> <property name="messageListener" ref="messageConsumer2" /> <!-- 配置多个消费者,可以是具体数值,也可以是数值区间,根据消息的规模来确定消费者的多少 --> <property name="concurrency" value="4-8"></property> </bean></beans>它们都放在src/main/resources下
pom.xml相关部分
<dependency><groupId>org.springframework</groupId><artifactId>spring-jms</artifactId><version>${org.springframework.version}</version></dependency><dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-all</artifactId><version>5.9.0</version><!--<scope>test</scope>--></dependency><dependency><groupId>org.apache.xbean</groupId><artifactId>xbean-spring</artifactId><version>3.7</version></dependency>
MessageJmsTemplate
public class MessageJmsTemplate extends org.springframework.jms.core.JmsTemplate{}
MessageConverter
import org.springframework.jms.support.converter.MessageConversionException;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.ObjectMessage;import javax.jms.Session;import java.io.Serializable;public class MessageConverter implements org.springframework.jms.support.converter.MessageConverter{ @Override public Message toMessage(Object o, Session session) throws JMSException, MessageConversionException { Message message=session.createObjectMessage((Serializable) o); int group=Integer.parseInt(((com.sap.c4c.wechat.model.Message)o).getContent()); message.setStringProperty("JMSXGroupID","group"+group);// message.setIntProperty("JMSXGroupSeq", -1); return message; } @Override public Object fromMessage(Message message) throws JMSException, MessageConversionException { ObjectMessage objMessage = (ObjectMessage) message; return objMessage.getObject(); }}
MessageProducer1
import com.sap.c4c.wechat.model.Message;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jms.core.JmsTemplate;import java.util.logging.Logger;public class MessageProducer1 { private static final Logger logger = Logger.getLogger(MessageProducer1.class.getName()); @Autowired private JmsTemplate jmsTemplate1; @Autowired private JmsTemplate jmsTemplate1_b; public void sendMessageToDefaultDestination(Message message) { logger.info("producer1: "+message.getContent()); if(Integer.parseInt(message.getContent())%3==0) { message.setContent(message.getContent() + "_b"); jmsTemplate1_b.convertAndSend(message); }else { jmsTemplate1.convertAndSend(message); } }}
MessageProducer2
import com.sap.c4c.wechat.model.Message;import org.springframework.beans.factory.annotation.Autowired;import java.util.logging.Logger;public class MessageProducer2 { private static final Logger logger = Logger.getLogger(MessageProducer2.class.getName()); @Autowired private MessageJmsTemplate jmsTemplate2; public void sendMessageToDefaultDestination(Message message) { logger.info("producer2: "+message.getContent()); jmsTemplate2.convertAndSend(message); }}
MessageConsumer1
import com.sap.c4c.wechat.model.Message;import com.sap.c4c.wechat.service.MessageService;import org.springframework.beans.factory.annotation.Autowired;import javax.jms.JMSException;import javax.jms.MessageListener;import javax.jms.ObjectMessage;import java.util.logging.Logger;public class MessageConsumer1 implements MessageListener { private static final Logger logger = Logger.getLogger(MessageConsumer1.class.getName()); @Autowired MessageService messageService; @Override public void onMessage(javax.jms.Message message) { try { ObjectMessage objMessage=(ObjectMessage) message; Object obj = objMessage.getObject(); Message wechatMessage = (Message) obj; //TODO logger.info("consumer1: "+wechatMessage.getContent()+" thread-"+Thread.currentThread().getName()); } catch (JMSException ex) { throw new RuntimeException(ex); } }}
MessageConsumer2
import com.sap.c4c.wechat.model.Message;import com.sap.c4c.wechat.service.MessageService;import org.springframework.beans.factory.annotation.Autowired;import javax.jms.JMSException;import javax.jms.MessageListener;import javax.jms.ObjectMessage;import java.util.logging.Logger;public class MessageConsumer2 implements MessageListener { private static final Logger logger = Logger.getLogger(MessageConsumer2.class.getName()); @Autowired MessageService messageService; @Override public void onMessage(javax.jms.Message message) { try { ObjectMessage objMessage=(ObjectMessage) message; Object obj = objMessage.getObject(); Message wechatMessage = (Message) obj; //TODO logger.info("consumer2: "+wechatMessage.getContent()+" thread-"+Thread.currentThread().getName()); } catch (JMSException ex) { throw new RuntimeException(ex); } }}
MessageController
import com.google.gson.JsonElement;import com.google.gson.JsonParser;import io.swagger.annotations.Api;import org.apache.commons.io.IOUtils;import org.apdplat.word.WordSegmenter;import org.apdplat.word.segmentation.Word;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.io.*;import java.net.HttpURLConnection;import java.net.URL;import java.util.List;@RestController("ControllerV1")@RequestMapping("/v1/message")@Api(value="Message")public class MessageController extends GenericController<MessageDTO, Message> {//这里的Message是一个Model,有String类型的content成员private static final Logger logger = LoggerFactory.getLogger(MessageController.class.getName());@Autowiredprivate MessageProducer1 messageProducer1;@Autowiredprivate MessageProducer2 messageProducer2;@RequestMapping(value = "/{id}",method = RequestMethod.GET)public void test(@PathVariable int id) throws Exception{Message message=new Message();message.setContent(id+"");if(id%2!=0)//oddmessageProducer1.sendMessageToDefaultDestination(message);else//evenmessageProducer2.sendMessageToDefaultDestination(message);}}这样模拟实现了多个queue,多个consumer的ActiveMQ
MessageConverter使用了消息的分组,运行发现JMSGroupID相同的总是在同一个线程(同一个Consumer2)中处理。
参考链接:
http://www.jeejava.com/embedded-activemq-and-spring-jms-integration/
http://activemq.apache.org/features.html
http://activemq.apache.org/message-groups.html
http://activemq.apache.org/spring-support.html
http://activemq.apache.org/how-do-i-embed-a-broker-inside-a-connection.html
http://elim.iteye.com/blog/1900937
http://isoftyh.iteye.com/blog/1774015
https://stackoverflow.com/questions/18802982/no-declaration-can-be-found-for-element-contextannotation-config
http://coderbase64.iteye.com/blog/2065528
https://codedependents.com/2009/10/16/efficient-lightweight-jms-with-spring-and-activemq/
http://www.blogjava.net/ldd600/archive/2010/11/02/336755.html
https://stackoverflow.com/questions/30183907/activemq-how-to-programmatically-monitor-embedded-broker
http://blog.csdn.net/u010248330/article/details/62429001
http://www.360doc.com/content/16/0406/18/203871_548376577.shtml
http://www.bubuko.com/infodetail-2065759.html
- Spring结合嵌入式ActiveMQ使用消息队列
- Spring集成ActiveMQ消息队列使用
- 结合spring使用jmsTemplate简单消息队列
- 消息队列ActiveMQ+Spring整合
- spring jms activeMQ 消息队列
- activeMQ+Spring-mvc结合使用
- JMS之Spring +activeMQ实现消息队列
- Java消息队列-Spring整合ActiveMq
- Java消息队列-Spring整合ActiveMq
- Java消息队列-Spring整合ActiveMq
- spring boot 集成activeMQ消息队列
- Java消息队列-Spring整合ActiveMq
- rabbitmq结合spring实现消息队列优先级
- java消息队列ActiveMQ的简单使用
- java消息队列ActiveMQ的简单使用
- PHP中使用ActiveMQ实现消息队列
- ActiveMQ消息队列的使用及应用
- 消息队列ActiveMQ的安装与使用
- AFNetworking的原理与基本使用
- lotus中密送,抄送,正常发送的区别
- 文章标题
- OkHttp新版本中的setSSLSocketFactory改动
- 路漫漫其修远兮
- Spring结合嵌入式ActiveMQ使用消息队列
- Eclipse下修改java文件默认编译路径
- 转载:Introducing the Software Testing Cupcake (Anti-Pattern)
- URI和URL的区别
- babel-polyfill让你放心用es6做开发
- spring 框架配置类
- Java中集合与数组互转总结
- JSONP跨域,CORS跨域,Hybrid APP跨域
- css类选择器使用