文档章节

JMS学习(四)-----Spring和ActiveMQ整合的完整实例

火龙战士
 火龙战士
发布于 2016/08/08 14:31
字数 2041
阅读 418
收藏 3

Spring和ActiveMQ整合的完整实例

源码下载:http://git.oschina.net/zhengweishan/JMS_Study_Demo

1、前言

我们基于Spring+JMS+ActiveMQ+Tomcat,做一个Spring4.2.6和ActiveMQ5.7.0整合实例,实现了Point-To-Point的异步队列消息和PUB/SUB(发布/订阅)模型,简单实例,不包含任何业务。

项目结构

2、配置文件

2.1 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.activemq.demo</groupId>
  <artifactId>SpringActiveMq</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>SpringActiveMq Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<org.springframework.version>4.2.6.RELEASE</org.springframework.version>
	</properties>
  
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>javax.servlet-api</artifactId>
		<version>3.1.0</version>
	</dependency>
	
	<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>

	<!-- activeMQ与spring整合所需要的包 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>

	<!-- activeMQ -->
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-core</artifactId>
			<version>5.7.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.xbean</groupId>
			<artifactId>xbean-spring</artifactId>
			<version>4.5</version>
		</dependency>

		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-core-asl</artifactId>
			<version>1.9.12</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-asl</artifactId>
			<version>1.9.12</version>
		</dependency>
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.4.3</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.4.3</version>
		</dependency>
	
  </dependencies>
  <build>
    <finalName>SpringActiveMq</finalName>
  </build>
</project>

2.2 spring-activeMQ.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd   
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/jms
        http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
        http://activemq.apache.org/schema/core
        http://activemq.apache.org/schema/core/activemq-core-5.7.0.xsd">

	<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://localhost:61616" />
	</bean>

	<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
	<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
		<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的pooledConnectionFactory -->
		<property name="targetConnectionFactory" ref="targetConnectionFactory" />
		<property name="sessionCacheSize" value="100" />
	</bean>

	<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
		<property name="connectionFactory" ref="connectionFactory" />
		<!-- 非pub/sub模型(发布/订阅),即队列模式 -->
		<property name="pubSubDomain" value="false" />
	</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" />
	</bean>
	<!-- 消息监听器 -->
	<bean id="consumerMessageListener" class="com.activemq.demo.ConsumerMessageListener" />

	<!-- 消息监听容器 -->
	<bean id="jmsContainer"
		class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="queueDestination" />
		<property name="messageListener" ref="consumerMessageListener" />
	</bean>

</beans>

2.3 servlet-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:task="http://www.springframework.org/schema/task"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	 http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd
	  http://www.springframework.org/schema/mvc
	  http://www.springframework.org/schema/mvc/spring-mvc.xsd
	  http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx.xsd"
	default-lazy-init="false">
    
   <mvc:annotation-driven >
    <!-- 消息转换器 -->
    <mvc:message-converters register-defaults="true">
      <bean class="org.springframework.http.converter.StringHttpMessageConverter">
        <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
      </bean>
      <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
      	<property name="supportedMediaTypes">
                 <list>
                        <value>text/html; charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                  </list>
        </property>
      </bean>  
    </mvc:message-converters>
  </mvc:annotation-driven>
  <!-- 静态资源   -->
    <mvc:resources mapping="/resources/**" location="/resources/"/>
    
   
    
    <!-- 中文乱码解决 -->
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >  
	    <property name="messageConverters">   
	        <list>   
	            <bean class = "org.springframework.http.converter.StringHttpMessageConverter">   
	                <property name = "supportedMediaTypes">
	                    <list>
	                        <value>text/plain;charset=UTF-8</value>   
	                    </list>   
	                </property>   
	            </bean>   
	        </list>   
	   </property>  
	</bean>
	<context:component-scan base-package="com.activemq.demo"/>
</beans>

2.4 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
	<display-name>dubbo_consumer</display-name>
	<description>dubbo_consumer test</description>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			classpath*:spring-activeMQ.xml
		</param-value>
	</context-param>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath*:servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

3、部署运行

部署之后访问:http://localhost:8081/SpringActiveMq/test/sendMessage,效果如下:

ActiveMq控制台:

4、spring-activeMQ.xml解析

4.1 配置ConnectionFactory

connectionFactory是Spring用于创建到JMS服务器链接的,Spring提供了多种connectionFactory,我们介绍两个SingleConnectionFactory和CachingConnectionFactory。

  1. SingleConnectionFactory:对于建立JMS服务器链接的请求会一直返回同一个链接,并且会忽略Connection的close方法调用。

  2. CachingConnectionFactory:继承了SingleConnectionFactory,所以它拥有SingleConnectionFactory的所有功能,同时它还新增了缓存功能,它可以缓存Session、MessageProducer和MessageConsumer。我们使用CachingConnectionFactory来作为示例。

Spring提供的ConnectionFactory只是Spring用于管理ConnectionFactory的,真正产生到JMS服务器链接的ConnectionFactory还得是由JMS服务厂商提供,并且需要把它注入到Spring提供的ConnectionFactory中。我们这里使用的是ActiveMQ实现的JMS,所以在我们这里真正的可以产生Connection的就应该是由ActiveMQ提供的ConnectionFactory。所以定义一个ConnectionFactory的完整代码应该如下所示:

 <!-- 连接池  -->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">  
    <property name="connectionFactory">  
        <bean class="org.apache.activemq.ActiveMQConnectionFactory">  
            <property name="brokerURL" value="tcp://localhost:61616" />  
        </bean>  
    </property>  
</bean>
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
	<property name="brokerURL" value="tcp://localhost:61616" />
</bean>

<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
	<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的pooledConnectionFactory -->
	<property name="targetConnectionFactory" ref="targetConnectionFactory" />
	<property name="sessionCacheSize" value="100" />
</bean>

或者这样配置:

 <!-- ActiveMQ 连接工厂 -->
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码-->
<amq:connectionFactory id="amqConnectionFactory"
    brokerURL="tcp://192.168.3.3: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>

4.2 配置生产者

配置好ConnectionFactory之后我们就需要配置生产者。生产者负责产生消息并发送到JMS服务器。但是我们要怎么进行消息发送呢?通常是利用Spring为我们提供的JmsTemplate类来实现的,所以配置生产者其实最核心的就是配置消息发送的JmsTemplate。对于消息发送者而言,它在发送消息的时候要知道自己该往哪里发,为此,我们在定义JmsTemplate的时候需要注入一个Spring提供的ConnectionFactory对象。

在利用JmsTemplate进行消息发送的时候,我们需要知道发送哪种消息类型:一个是点对点的ActiveMQQueue,另一个就是支持订阅/发布模式的ActiveMQTopic。如下所示:

<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
	<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
	<property name="connectionFactory" ref="connectionFactory" />
	<!-- 非pub/sub模型(发布/订阅),即队列模式 如果value是true pub/sub模型(发布/订阅) -->
	<property name="pubSubDomain" value="false" />
</bean>

4.3 配置消费者

生产者往指定目的地Destination发送消息后,接下来就是消费者对指定目的地的消息进行消费了。那么消费者是如何知道有生产者发送消息到指定目的地Destination了呢?每个消费者对应每个目的地都需要有对应的MessageListenerContainer。对于消息监听容器而言,除了要知道监听哪个目的地之外,还需要知道到哪里去监听,也就是说它还需要知道去监听哪个JMS服务器,通过配置MessageListenerContainer的时候往里面注入一个ConnectionFactory来实现的。所以我们在配置一个MessageListenerContainer的时候有三个属性必须指定:一个是表示从哪里监听的ConnectionFactory;一个是表示监听什么的Destination;一个是接收到消息以后进行消息处理的MessageListener。

<!-- 消息监听器 -->
<bean id="consumerMessageListener" class="com.activemq.demo.ConsumerMessageListener" />

<!-- 消息监听容器 -->
<bean id="jmsContainer"
	class="org.springframework.jms.listener.DefaultMessageListenerContainer">
	<property name="connectionFactory" ref="connectionFactory" />
	<property name="destination" ref="queueDestination" />
	<property name="messageListener" ref="consumerMessageListener" />
</bean>

5、总结

Spring提供了对JMS的支持,ActiveMQ提供了很好的实现,而此时我们已经将两者完美的结合在了一起。

© 著作权归作者所有

火龙战士

火龙战士

粉丝 120
博文 138
码字总数 101234
作品 0
北京
后端工程师
私信 提问
一步一步Spring整合JMS

1.1 JMS简介 JMS的全称是Java Message Service,即Java消息服务。它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息。把它应用到实际的业务需求中的话...

摆渡者
2015/08/31
425
0
activeMQ5官方文档翻译-初始化配置

首先你需要把jar包加到classpath 所需的jar包 为了使ActiveMQ更容易使用,默认的activemq-all.jar包包含了所有需要用到的库文件。如果你喜欢以明确的控制jar包的方式来使用ActiveMQ,那下面是...

z_jordon
2015/05/29
320
0
spring整合jms系列之----点对点(一)

JMS作为一个支持点对点(PTP)和订阅式(pub/sub)式的消息中间件,为很多项目开发者所使用。Spring对JMS提供了很好的支持,可以通过JmsTemplate来方便地实现消息服务,由于JMS对Spring的支持...

码上中国博客
2015/11/12
510
0
JMS配置说明-----activeMQ-5.6

1 简介 activeMQ是一个完全支持JMS1.1 和J2EE规范的JMS Provider实现; 尽管规范出台已经是很久的事情了,但JMS在当今的J2EE应用中仍然扮演着特殊的地位; 特性列表 多种语言和协议编写客户端...

次渠龙哥
2018/06/26
0
0
ActiveMQ 5.10.0 发布,JMS 消息服务器

ActiveMQ 5.10.0 发布,此版本修复了超过 200 个问题,引入了大量的改进,特别是 MQTT 和 AMQP 支持方面的。更新内容如下: Java 8 支持 Apache Shiro 安全插件 - http://activemq.apache.o...

chaun
2014/08/05
1K
1

没有更多内容

加载失败,请刷新页面

加载更多

redis 不同数据结构的使用场景?

1. string string 类型也就是 key-value 类型 常用命令:get、set、incr 应用场景:string 是最常用的一种数据类型 2. list 常用命令:lpush,rpush,brpop,blpop 应用场景:作为消息队列,因为...

happywe
23分钟前
4
0
PG jdbc

import java.sql.DriverManager;import java.sql.Connection;import java.sql.SQLException;import java.sql.ResultSet;import java.sql.Statement; public class PG{ public stat......

MtrS
27分钟前
3
0
Java工程师学习指南(中级篇)

Java工程师学习指南 中级篇 最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好。原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我写...

Java技术江湖
39分钟前
3
0
java 三元表达式

例子:C=A>B ? 100 :200; 这条语句的意思是,如果A>B的话,就将100赋给C,否则就将200赋给C;

无名氏的程序员
50分钟前
6
0
针对回流和重绘的渲染优化--公司分享

如果是你,你会如何实现浏览器内核,你认为的浏览器渲染的流程是怎么样的 工作开发中,你有做过哪些关于性能优化的工作(代码),或者目前的业务中有哪些是可以做优化的 浏览器渲染机制 什么...

莫西摩西
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部