ActiveMQ实战(六)--Spring整合ActiveMQ实现队列和主题发布订阅通信
来源:互联网 发布:java运行环境变量配置 编辑:程序博客网 时间:2024/04/29 01:36
一、新建Maven项目
工具使用的是IDEA,具体操作如下,New-->Project
创建的项目如下所示
然后在main下新建java目录、创建好之后、在java目录上右键转换为source
完整的项目结构如下:
二、添加依赖
POM.XML文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.fendo.activemq</groupId> <artifactId>activemq_demo</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>activemq_demo Maven Webapp</name> <url>http://maven.apache.org</url> <developers> <developer> <id>fendo</id> <name>fendo</name> <email>fendo@qq.com</email> </developer> </developers> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <fastjson.vesrion>1.2.35</fastjson.vesrion> <activemq.version>5.13.2</activemq.version> <activemq-pool.version>5.15.0</activemq-pool.version> <spring.version>4.1.9.RELEASE</spring.version> <junit.version>4.12</junit.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</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-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</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-expression</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</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-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.apache.xbean</groupId> <artifactId>xbean-spring</artifactId> <version>4.4</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.vesrion}</version> </dependency> <!-- Active MQ --> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> <version>${activemq.version}</version> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> <version>${activemq-pool.version}</version> </dependency> <!-- spring-jms --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>${spring.version}</version> </dependency> <!-- spring --> <!--单元测试--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>activemq_demo</finalName> </build></project>
三、添加配置文件
web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>Archetype Created Web Application</display-name> <!-- Log4J Start --> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j.properties</param-value> </context-param> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>6000</param-value> </context-param> <context-param> <param-name>log4jExposeWebAppRoot</param-name> <param-value>false</param-value> </context-param> <!-- Spring Log4J config --> <!-- Spring 编码过滤器 start --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Spring 编码过滤器 End --> <!-- Spring Application Context Listener Start --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/spring-context*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Spring Application Context Listener End --> <!-- Spring MVC Config Start --> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <!-- Spring MVC Config End --></web-app>
spring-context.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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <mvc:annotation-driven /> <!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。 --> <context:component-scan base-package="com.fendo.activemq"><!-- base-package 如果多个,用“,”分隔 --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan></beans>
spring-mvc.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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <mvc:annotation-driven /> <mvc:default-servlet-handler/> <!-- 使用Annotation自动注册Bean,只扫描@Controller --> <context:component-scan base-package="com.fendo.activemq" use-default-filters="false"><!-- base-package 如果多个,用“,”分隔 --> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/" /> <property name="suffix" value=".jsp" /> </bean></beans>
spring-contexe-activemq.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:amq="http://activemq.apache.org/schema/core" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.1.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.13.2.xsd "> <!-- ActiveMQ 连接工厂 --> <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供--> <!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码--> <amq:connectionFactory id="amqConnectionFactory" brokerURL="tcp://127.0.0.1:61616" userName="admin" password="admin" /> <!-- Spring Caching连接工厂 --> <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --> <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --> <property name="targetConnectionFactory" ref="amqConnectionFactory"></property> <!-- 同上,同理 --> <!-- <constructor-arg ref="amqConnectionFactory" /> --> <!-- Session缓存数量 --> <property name="sessionCacheSize" value="100" /> </bean> <!-- Spring JMS Template --> <!-- 消息生产者 --> <!-- Queue类型 --> <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate"> <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --> <constructor-arg ref="connectionFactory"></constructor-arg> <!-- 非pub/sub模型(发布/订阅),即队列模式 --> <property name="pubSubDomain" value="false" /> </bean> <!-- 定义JmsTemplate的Topic类型 --> <bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate"> <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --> <constructor-arg ref="connectionFactory" /> <!-- pub/sub模型(发布/订阅) --> <property name="pubSubDomain" value="true" /> </bean> <!--Spring JmsTemplate 的消息生产者 end --> <!-- 消息监听器 --> <!--队列--> <bean id="QueueConsumer_1" class="com.fendo.activemq.service.consumer.QueueConsumer_1"></bean> <bean id="QueueConsumer_2" class="com.fendo.activemq.service.consumer.QueueConsumer_2"></bean> <!--主题--> <bean id="TopicConsumer_1" class="com.fendo.activemq.service.consumer.TopicConsumer_1"></bean> <bean id="TopicConsumer_2" class="com.fendo.activemq.service.consumer.TopicConsumer_2"></bean> <!-- 消息消费者 start --> <!-- 定义Queue监听器容器 --> <jms:listener-container destination-type="queue" container-type="default" connection-factory="connectionFactory" acknowledge="auto"> <jms:listener destination="queue" ref="QueueConsumer_1" /> <jms:listener destination="queue" ref="QueueConsumer_2" /> </jms:listener-container> <!-- 定义Topic监听器容器 --> <jms:listener-container destination-type="topic" container-type="default" connection-factory="connectionFactory" acknowledge="auto"> <jms:listener destination="topic" ref="TopicConsumer_1" /> <jms:listener destination="topic" ref="TopicConsumer_2" /> </jms:listener-container> <!-- 消息消费者 end --> <!-- 定义队列目的地 ,点对点 --> <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>
log4j.properties
### direct log messages to stdout and logFile###log4j.rootCategory=INFO, stdout,logFile# OpenSymphony Stufflog4j.logger.com.opensymphony=INFOlog4j.logger.org.apache.commons=INFO # Spring Stufflog4j.logger.org.springframework=INFOlog4j.logger.org.springframework.oxm=INFOlog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=[\u65F6\u95F4\:%d{yyyy-MM-dd hh\:mm\:ss}] [\u7EA7\u522B\:%p] [\u7C7B\:%c] [\u6D88\u606F\:%m] %n log4j.appender.logFile=org.apache.log4j.RollingFileAppenderlog4j.appender.logFile.File=D\:\\demo.loglog4j.appender.logFile.layout=org.apache.log4j.PatternLayoutlog4j.appender.logFile.layout.ConversionPattern=[\u65F6\u95F4\:%d{yyyy-MM-dd hh\:mm\:ss}] [\u7EA7\u522B\:%p] [\u7C7B\:%c] [\u6D88\u606F\:%m] %n log4j.appender.logFile.MaxFileSize = 5MBlog4j.appender.logFile.MaxBackupIndex =3
四、添加生产者消费者
4.1、Queue队列通信
新建消息生产者:
package com.fendo.activemq.service.producer;import javax.jms.Destination;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.Service;/** * @version V1.0 * @Author fendo * @ClassName ProducerService * @PackageName com.fendo.activemq.service * @Description 队列-消息生产者 Service * @Data 2017-09-21 10:47 **/@Servicepublic class QueueProducerService { @Autowired private JmsTemplate jmsQueueTemplate; //发送消息 public void sendMessage(Destination destination,final String message) { System.out.println("QueueProducerService发送消息:"+message); jmsQueueTemplate.send(destination, new MessageCreator() { @Override public Message createMessage(Session session) throws JMSException { return session.createTextMessage(message); } }); }}
然后创建多个消息消费者
消费者1:
package com.fendo.activemq.service.consumer;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;/** * @version V1.0 * @Author fendo * @ClassName QueueConsumer_1 * @PackageName com.fendo.activemq.listener * @Description 队列消费者1 * @Data 2017-09-21 10:47 **/public class QueueConsumer_1 implements MessageListener { //当收到消息后,自动调用该方法 @Override public void onMessage(Message message) { TextMessage tm = (TextMessage) message; try { System.out.println("QueueConsumer_1接收到消息内容是:" + tm.getText()); } catch (JMSException e) { e.printStackTrace(); } }}
package com.fendo.activemq.service.consumer;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;/** * @version V1.0 * @Author fendo * @ClassName QueueConsumer_2 * @PackageName com.fendo.activemq.listener * @Description 队列消费者2 * @Data 2017-09-21 10:47 **/public class QueueConsumer_2 implements MessageListener { //当收到消息后,自动调用该方法 @Override public void onMessage(Message message) { TextMessage tm = (TextMessage) message; try { System.out.println("QueueConsumer_2接收到消息内容是:" + tm.getText()); } catch (JMSException e) { e.printStackTrace(); } }}
4.2、Topic通信
创建Topic生产者:
package com.fendo.activemq.service.producer;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jms.core.JmsTemplate;import org.springframework.jms.core.MessageCreator;import org.springframework.stereotype.Service;import javax.jms.Destination;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.Session;/** * @version V1.0 * @Author fendo * @ClassName TopicConsumerService * @PackageName com.fendo.activemq.service * @Description 主题-生产者 Service * @Data 2017-09-21 10:47 **/@Servicepublic class TopicProducerService { @Autowired private JmsTemplate jmsTopicTemplate; //发送消息 public void sendMessage(Destination destination, final String message) { System.out.println("向主题" + destination.toString() + "发送了消息------------" + message); jmsTopicTemplate.send(destination, new MessageCreator() { @Override public Message createMessage(Session session) throws JMSException { return session.createTextMessage(message); } }); }}
然后创建多个Topic消费者:
package com.fendo.activemq.service.consumer;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;/** * @version V1.0 * @Author fendo * @ClassName TopicConsumer_1 * @PackageName com.fendo.activemq.service * @Description 主题-消息消费者1 * @Data 2017-09-21 10:47 **/public class TopicConsumer_1 implements MessageListener { @Override public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { System.out.println("TopicConsumer_1接收到消息内容是:" + textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } }}
package com.fendo.activemq.service.consumer;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;/** * @version V1.0 * @Author fendo * @ClassName TopicConsumer_2 * @PackageName com.fendo.activemq.service * @Description 主题-消息消费者2 * @Data 2017-09-21 10:47 **/public class TopicConsumer_2 implements MessageListener { @Override public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { System.out.println("TopicConsumer_2接收到消息内容是:" + textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } }}
Controller类:
package com.fendo.activemq.controller;import com.fendo.activemq.service.producer.QueueProducerService;import com.fendo.activemq.service.producer.TopicProducerService;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.servlet.ModelAndView;import javax.annotation.Resource;import javax.jms.Destination;/** * @version V1.0 * @Author fendo * @ClassName ActivemqController * @PackageName com.fendo.activemq.controller * @Description Activemq Controller * @Data 2017-09-21 10:47 **/@Controllerpublic class ActivemqController { private Logger logger = LoggerFactory.getLogger(ActivemqController.class); @Autowired private QueueProducerService queueProducerService; @Autowired private TopicProducerService topicProducerService; @Resource @Qualifier("queueDestination") private Destination queueDestination; @Resource @Qualifier("topicDestination") private Destination topicDestination; @RequestMapping("") public ModelAndView activemq(){ ModelAndView mv = new ModelAndView(); mv.setViewName("index"); return mv; } /** * 去发消息页面 * @return */ @RequestMapping(value="/producer",method= RequestMethod.GET) public ModelAndView producer(){ ModelAndView mv = new ModelAndView(); mv.setViewName("producer"); return mv; } /** * 发送消息 * @param message * @return */ @RequestMapping(value="/onsend",method=RequestMethod.POST) public ModelAndView producer(@RequestParam("message") String message,@RequestParam("sendflag") String sendflag) { System.out.println("------------send to jms------------"); ModelAndView mv = new ModelAndView(); //1 主题 2 队列 if("1".equals(sendflag)){ System.out.println("topic生产者产生消息:" + message); topicProducerService.sendMessage(topicDestination, "topic生产者产生消息:" + message); }else { System.out.println("队列生产者产生消息:" + message); queueProducerService.sendMessage(queueDestination, "队列生产者产生消息:" + message); } mv.setViewName("index"); return mv; }}
五、测试项目
然后创建消息生产者页面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>生产者</title></head><body> <h1>生产者</h1> <h2>去队列发消息</h2> <form action="${pageContext.request.contextPath}/onsend" method="post"> 发送的内容:<textarea name="message" ></textarea> <input type="text" style="display: none" name="sendflag" value="2" /> <input type="submit" value="提交" /> </form> <h2>去主题发消息</h2> <form action="${pageContext.request.contextPath}/onsend" method="post"> 发送的内容:<textarea name="message" ></textarea> <input type="text" style="display: none" name="sendflag" value="1" /> <input type="submit" value="提交" /> </form> <h2><a href="${pageContext.request.contextPath}/">返回主页</a></h2></body></html>
效果如下:
可以分别发送队列和主题,发送的效果如下:
从接收的消息可以看出出队列模型和Topic模型的区别,Queue只能由一个消费者接收,其他Queue中的成员无法接受到被已消费的信息,而Topic则可以,只要是订阅了Topic的消费者,全部可以获取到生产者发布的信息。
完整项目如下:http://download.csdn.net/download/u011781521/10151680
阅读全文
0 0
- ActiveMQ实战(六)--Spring整合ActiveMQ实现队列和主题发布订阅通信
- ActiveMQ实战(五)--Spring整合ActiveMQ实现点对点与主题发布订阅通信
- ActiveMQ和spring整合,订阅主题和消息消费
- ActiveMQ实战(三)--ActiveMQ的通信方式之主题发布订阅式(publish-subscribe)
- Spring整合activeMq(二):发布订阅模式
- Spring+ActiveMQ实现消息收发和订阅
- spring整合activeMQ-摘要(订阅者和发布者)
- ActiveMQ实战之 Topic发布订阅消息
- ActiveMQ实战之 Topic发布订阅消息
- ActiveMQ实战之 Topic发布订阅消息
- ActiveMQ实战之 Topic发布订阅消息
- ActiveMQ实战之 Topic发布订阅消息
- ActiveMQ和spring整合
- ActiveMQ和spring整合
- Spring和ActiveMQ整合
- ActiveMQ之队列和主题
- ActiveMQ之队列和主题
- 消息队列ActiveMQ+Spring整合
- LVS原理与使用(1)
- linux的rsync工具的常用选项及ssh同步介绍
- SignalR入门
- [Leetcode] 513. Find Bottom Left Tree Value 解题报告
- H5 video 标签 播放事件 视频加载完成事件 获取视频播放进度时间
- ActiveMQ实战(六)--Spring整合ActiveMQ实现队列和主题发布订阅通信
- Call ANSYS from python
- 数字货币的诞生是否影响了互联网金融未来发展方向
- react-native Android打包apk
- SpringMVC上传文件的三种方法
- linux CentOS7 安装 RabbitMQ 3.6.3, Erlang 19.0
- Android 生产jar包
- Azkaban编译及WebServer模式部署
- 无法定位序数4540于动态链接库LIBEAY32.dll上(以及其它无法定位序数的解决方案)