MQ消息队列整合(二)

一. 新建一个Maven工程,并配置pom文件如下:

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.     <modelVersion>4.0.0</modelVersion>  
  4.   
  5.     <groupId>com.chhliu.myself</groupId>  
  6.     <artifactId>activemq_start</artifactId>  
  7.     <version>0.0.1-SNAPSHOT</version>  
  8.     <packaging>jar</packaging>  
  9.   
  10.     <name>activemq_start</name>  
  11.     <url>http://maven.apache.org</url>  
  12.   
  13.     <properties>  
  14.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  15.         <spring-version>3.2.5.RELEASE</spring-version>  
  16.     </properties>  
  17.   
  18.     <dependencies>  
  19.         <dependency>  
  20.             <groupId>junit</groupId>  
  21.             <artifactId>junit</artifactId>  
  22.             <version>4.10</version>  
  23.             <scope>test</scope>  
  24.         </dependency>  
  25.         <dependency>  
  26.             <groupId>org.springframework</groupId>  
  27.             <artifactId>spring-context</artifactId>  
  28.             <version>${spring-version}</version>  
  29.         </dependency>  
  30.         <dependency>  
  31.             <groupId>org.springframework</groupId>  
  32.             <artifactId>spring-jms</artifactId>  
  33.             <version>${spring-version}</version>  
  34.         </dependency>  
  35.         <dependency>  
  36.             <groupId>org.springframework</groupId>  
  37.             <artifactId>spring-test</artifactId>  
  38.             <version>${spring-version}</version>  
  39.         </dependency>  
  40.         <dependency>  
  41.             <groupId>javax.annotation</groupId>  
  42.             <artifactId>jsr250-api</artifactId>  
  43.             <version>1.0</version>  
  44.         </dependency>  
  45.         <dependency>  
  46.             <groupId>org.apache.activemq</groupId>  
  47.             <artifactId>activemq-all</artifactId>  
  48.             <version>5.13.3</version>  
  49.         </dependency>  
  50.         <dependency>  
  51.             <groupId>org.apache.commons</groupId>  
  52.             <artifactId>commons-pool2</artifactId>  
  53.             <version>2.0</version>  
  54.         </dependency>  
  55.     </dependencies>  
  56. </project>  
<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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.chhliu.myself</groupId>
	<artifactId>activemq_start</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>activemq_start</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring-version>3.2.5.RELEASE</spring-version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.10</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<dependency>
			<groupId>javax.annotation</groupId>
			<artifactId>jsr250-api</artifactId>
			<version>1.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-all</artifactId>
			<version>5.13.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
			<version>2.0</version>
		</dependency>
	</dependencies>
</project>
二. 配置连接工厂(ConnectionFactory)

Spring给我们提供了如下的连接工厂:


其中SingleConnectionFactory保证每次返回的都是同一个连接,CachingConnectionFactory继承了SingleConnectionFactory,在保证同一连接的同时,增加了缓存的功能,可以缓存Session以及生产者,消费者。当然,JMS提供的连接工厂只是用来实现管理的,并不是真正连接MQ的,真正的连接工厂需要具体的MQ厂商提供,下面我们以ActiveMQ为例来说明,配置如下:

  1. <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->  
  2.     <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">  
  3.         <property name="brokerURL" value="tcp://localhost:61616" />  
  4.     </bean>  
  5. <bean id="connectionFactory"  
  6.         class="org.springframework.jms.connection.SingleConnectionFactory">  
  7.         <property name="targetConnectionFactory" ref="targetConnectionFactory" />  
  8.     </bean>  
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://localhost:61616" />
	</bean>
<bean id="connectionFactory"
		class="org.springframework.jms.connection.SingleConnectionFactory">
		<property name="targetConnectionFactory" ref="targetConnectionFactory" />
	</bean>

为了减少我们连接的资源消耗,ActiveMQ为我们提供了一个连接工厂管理池--PooledConnectionFactory,通过连接工厂池,可以将Connection,Session等都放在池里面,用的时候直接返回池里面的内容,无需临时建立连接,节约开销。配置如下:

  1. <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->  
  2.     <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">  
  3.         <property name="brokerURL" value="tcp://localhost:61616" />  
  4.     </bean>  
  5.   
  6.     <!-- 通过往PooledConnectionFactory注入一个ActiveMQConnectionFactory可以用来将Connection,Session和MessageProducer池化这样可以大大减少我们的资源消耗, -->  
  7.     <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">  
  8.         <property name="connectionFactory" ref="targetConnectionFactory" />  
  9.         <property name="maxConnections" value="10" />  
  10.     </bean>  
  11.   
  12.     <bean id="connectionFactory"  
  13.         class="org.springframework.jms.connection.SingleConnectionFactory">  
  14.         <property name="targetConnectionFactory" ref="pooledConnectionFactory" />  
  15.     </bean>  
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://localhost:61616" />
	</bean>

	<!-- 通过往PooledConnectionFactory注入一个ActiveMQConnectionFactory可以用来将Connection,Session和MessageProducer池化这样可以大大减少我们的资源消耗, -->
	<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
		<property name="connectionFactory" ref="targetConnectionFactory" />
		<property name="maxConnections" value="10" />
	</bean>

	<bean id="connectionFactory"
		class="org.springframework.jms.connection.SingleConnectionFactory">
		<property name="targetConnectionFactory" ref="pooledConnectionFactory" />
	</bean>
三. 配置JmsTemplate

配置好连接工厂之后,就需要配置JMS的JmsTemplate,JmsTemplate的作用和JdbcTemplate类似,我们发送和接收消息,都是通过JmsTemplate来实现的,配置如下:

  1. <!-- 配置生产者:配置好ConnectionFactory之后我们就需要配置生产者。生产者负责产生消息并发送到JMS服务器,这通常对应的是我们的一个业务逻辑服务实现类。 但是我们的服务实现类是怎么进行消息的发送的呢?这通常是利用Spring为我们提供的JmsTemplate类来实现的, 所以配置生产者其实最核心的就是配置进行消息发送的JmsTemplate。对于消息发送者而言,它在发送消息的时候要知道自己该往哪里发, 为此,我们在定义JmsTemplate的时候需要往里面注入一个Spring提供的ConnectionFactory对象 -->  
  2.     <!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->  
  3.     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
  4.         <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->  
  5.         <property name="connectionFactory" ref="connectionFactory" />  
  6.     </bean>  
<!-- 配置生产者:配置好ConnectionFactory之后我们就需要配置生产者。生产者负责产生消息并发送到JMS服务器,这通常对应的是我们的一个业务逻辑服务实现类。 但是我们的服务实现类是怎么进行消息的发送的呢?这通常是利用Spring为我们提供的JmsTemplate类来实现的, 所以配置生产者其实最核心的就是配置进行消息发送的JmsTemplate。对于消息发送者而言,它在发送消息的时候要知道自己该往哪里发,	为此,我们在定义JmsTemplate的时候需要往里面注入一个Spring提供的ConnectionFactory对象 -->
	<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
		<property name="connectionFactory" ref="connectionFactory" />
	</bean>
四. 生产者实现

配置完这些之后,我们就可以写代码实现生产者和消费者了,生产者主要用来生产消息,并向目的队列中推送消息,接口定义如下:

  1. public interface ProducerService {  
  2.     void sendMessage(Destination destination, final String message);  
  3. }  
public interface ProducerService {
	void sendMessage(Destination destination, final String message);
}

实现类代码如下:

  1. @Service("producerServiceImpl")  
  2. public class ProducerServiceImpl implements ProducerService {  
  3.       
  4.     /** 
  5.      * 注入JmsTemplate 
  6.      */  
  7.     @Resource(name="jmsTemplate")  
  8.     private JmsTemplate jTemplate;  
  9.   
  10.     /** 
  11.      * attention: 
  12.      * Details:发送消息 
  13.      * @author chhliu 
  14.      * 创建时间:2016-7-28 下午2:33:14 
  15.      * @param destination 
  16.      * @param message 
  17.      */  
  18.     @Override  
  19.     public void sendMessage(Destination receivedestination, final String message) {  
  20.           
  21.         System.out.println("================生产者创建了一条消息==============");  
  22.         jTemplate.send(receivedestination, new MessageCreator() {  
  23.               
  24.             @Override  
  25.             public Message createMessage(Session session) throws JMSException {  
  26.                 return session.createTextMessage("hello acticeMQ:"+message);  
  27.             }  
  28.         });  
  29.     }  
  30. }  
@Service("producerServiceImpl")
public class ProducerServiceImpl implements ProducerService {
	
	/**
	 * 注入JmsTemplate
	 */
	@Resource(name="jmsTemplate")
	private JmsTemplate jTemplate;

	/**
	 * attention:
	 * Details:发送消息
	 * @author chhliu
	 * 创建时间:2016-7-28 下午2:33:14
	 * @param destination
	 * @param message
	 */
	@Override
	public void sendMessage(Destination receivedestination, final String message) {
		
		System.out.println("================生产者创建了一条消息==============");
		jTemplate.send(receivedestination, new MessageCreator() {
			
			@Override
			public Message createMessage(Session session) throws JMSException {
				return session.createTextMessage("hello acticeMQ:"+message);
			}
		});
	}
}
五. 消费者实现

假设生产者已经创建了一条消息,并推送到了对应的队列中,消费者需要从这个队列中取出消息,并同时回复一条报文,自己已经收到了这条消息,为了测试回复报文的功能,我们下面会将回复报文放到另一个队列中,此例使用同步接收消息的方式,而不是异步监听的方式实现,接口定义如下:

  1. public interface ConsumerService {  
  2.     String receiveMessage(Destination destination, Destination replyDestination);  
  3. }  
public interface ConsumerService {
	String receiveMessage(Destination destination, Destination replyDestination);
}

实现类代码如下:

  1. @Service("consumerServiceImpl")  
  2. public class ConsumerServiceImpl implements ConsumerService {  
  3.       
  4.     /** 
  5.      * 注入JmsTemplate 
  6.      */  
  7.     @Resource(name="jmsTemplate")  
  8.     private JmsTemplate jTemplate;  
  9.       
  10.     /** 
  11.      * attention: 
  12.      * Details:接收消息,同时回复消息 
  13.      * @author chhliu 
  14.      * 创建时间:2016-7-28 下午2:39:45 
  15.      * @param destination 
  16.      * @return 
  17.      */  
  18.     @Override  
  19.     public String receiveMessage(Destination destination, Destination replyDestination) {  
  20.         /** 
  21.          * 接收消息队列中的消息 
  22.          */  
  23.         Message message = jTemplate.receive(destination);  
  24.         try {  
  25.             /** 
  26.              * 此处为了更好的容错性,可以使用instanceof来判断下消息类型 
  27.              */  
  28.             if(message instanceof TextMessage){  
  29.                 String receiveMessage =  ((TextMessage) message).getText();  
  30.                 System.out.println("收到生产者的消息:"+receiveMessage);  
  31.                 /** 
  32.                  * 收到消息之后,将回复报文放到回复队列里面去 
  33.                  */  
  34.                 jTemplate.send(replyDestination, new MessageCreator() {  
  35.                       
  36.                     @Override  
  37.                     public Message createMessage(Session session) throws JMSException {  
  38.                         return session.createTextMessage("消费者已经收到生产者的消息了,这是一条确认报文!");  
  39.                     }  
  40.                 });  
  41.               return receiveMessage;  
  42.             }  
  43.         } catch (JMSException e) {  
  44.             e.printStackTrace();  
  45.         }  
  46.         return "";  
  47.     }  
  48. }  
@Service("consumerServiceImpl")
public class ConsumerServiceImpl implements ConsumerService {
	
	/**
	 * 注入JmsTemplate
	 */
	@Resource(name="jmsTemplate")
	private JmsTemplate jTemplate;
	
	/**
	 * attention:
	 * Details:接收消息,同时回复消息
	 * @author chhliu
	 * 创建时间:2016-7-28 下午2:39:45
	 * @param destination
	 * @return
	 */
	@Override
	public String receiveMessage(Destination destination, Destination replyDestination) {
		/**
		 * 接收消息队列中的消息
		 */
		Message message = jTemplate.receive(destination);
		try {
			/**
			 * 此处为了更好的容错性,可以使用instanceof来判断下消息类型
			 */
			if(message instanceof TextMessage){
				String receiveMessage =  ((TextMessage) message).getText();
				System.out.println("收到生产者的消息:"+receiveMessage);
				/**
				 * 收到消息之后,将回复报文放到回复队列里面去
				 */
				jTemplate.send(replyDestination, new MessageCreator() {
					
					@Override
					public Message createMessage(Session session) throws JMSException {
						return session.createTextMessage("消费者已经收到生产者的消息了,这是一条确认报文!");
					}
				});
              return receiveMessage;
			}
		} catch (JMSException e) {
			e.printStackTrace();
		}
		return "";
	}
}
生产者和消费者实现之后,我们要做的就是配置队列了,下面给出项目完整的配置文件:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache"  
  6.     xmlns:jpa="http://www.springframework.org/schema/data/jpa"  
  7.   
  8.     xsi:schemaLocation="http://www.springframework.org/schema/beans     
  9.           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd     
  10.           http://www.springframework.org/schema/context     
  11.           http://www.springframework.org/schema/context/spring-context-3.2.xsd     
  12.           http://www.springframework.org/schema/aop     
  13.           http://www.springframework.org/schema/aop/spring-aop-3.2.xsd     
  14.           http://www.springframework.org/schema/tx      
  15.           http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
  16.           http://www.springframework.org/schema/cache   
  17.           http://www.springframework.org/schema/cache/spring-cache-3.2.xsd  
  18.           http://www.springframework.org/schema/data/jpa  
  19.           http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd">  
  20.   
  21.     <!-- 扫描注解包 -->  
  22.     <context:annotation-config />  
  23.     <context:component-scan base-package="com.chhliu.myself.activemq.start"></context:component-scan>  
  24.     <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">  
  25.         <property name="brokerURL" value="tcp://localhost:61616" />  
  26.     </bean>  
  27.     <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">  
  28.         <property name="connectionFactory" ref="targetConnectionFactory" />  
  29.         <property name="maxConnections" value="10" />  
  30.     </bean>  
  31.     <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">  
  32.         <property name="targetConnectionFactory" ref="pooledConnectionFactory" />  
  33.     </bean>  
  34.     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
  35.         <property name="connectionFactory" ref="connectionFactory" />  
  36.     </bean>  
  37.     <!-- 在真正利用JmsTemplate进行消息发送的时候,我们需要知道消息发送的目的地,即destination。 在Jms中有一个用来表示目的地的Destination接口,它里面没有任何方法定义,只是用来做一个标识而已。当我们在使用JmsTemplate进行消息发送时没有指定destination的时候将使用默认的Destination。 默认Destination可以通过在定义jmsTemplate bean对象时通过属性defaultDestination或defaultDestinationName来进行注入, defaultDestinationName对应的就是一个普通字符串 -->  
  38.     <!--这个是队列目的地,点对点的 -->  
  39.     <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">  
  40.         <constructor-arg>  
  41.             <value>NTF_MOCK_INPUT</value>  
  42.         </constructor-arg>  
  43.     </bean>  
  44.     <!--这个是回复队列,点对点的 -->  
  45.     <bean id="responseQueue" class="org.apache.activemq.command.ActiveMQQueue">  
  46.         <constructor-arg>  
  47.             <value>NTF_MOCK_OUTPUT</value>  
  48.         </constructor-arg>  
  49.     </bean>  
  50. </beans>  
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"

	xsi:schemaLocation="http://www.springframework.org/schema/beans   
          http://www.springframework.org/schema/beans/spring-beans-3.2.xsd   
          http://www.springframework.org/schema/context   
          http://www.springframework.org/schema/context/spring-context-3.2.xsd   
          http://www.springframework.org/schema/aop   
          http://www.springframework.org/schema/aop/spring-aop-3.2.xsd   
          http://www.springframework.org/schema/tx    
          http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
          http://www.springframework.org/schema/cache 
          http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
          http://www.springframework.org/schema/data/jpa
          http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd">

	<!-- 扫描注解包 -->
	<context:annotation-config />
	<context:component-scan base-package="com.chhliu.myself.activemq.start"></context:component-scan>
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://localhost:61616" />
	</bean>
	<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
		<property name="connectionFactory" ref="targetConnectionFactory" />
		<property name="maxConnections" value="10" />
	</bean>
	<bean id="connectionFactory"	class="org.springframework.jms.connection.SingleConnectionFactory">
		<property name="targetConnectionFactory" ref="pooledConnectionFactory" />
	</bean>
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="connectionFactory" />
	</bean>
	<!-- 在真正利用JmsTemplate进行消息发送的时候,我们需要知道消息发送的目的地,即destination。 在Jms中有一个用来表示目的地的Destination接口,它里面没有任何方法定义,只是用来做一个标识而已。当我们在使用JmsTemplate进行消息发送时没有指定destination的时候将使用默认的Destination。 默认Destination可以通过在定义jmsTemplate bean对象时通过属性defaultDestination或defaultDestinationName来进行注入, defaultDestinationName对应的就是一个普通字符串 -->
	<!--这个是队列目的地,点对点的 -->
	<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg>
			<value>NTF_MOCK_INPUT</value>
		</constructor-arg>
	</bean>
    <!--这个是回复队列,点对点的 -->
	<bean id="responseQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg>
			<value>NTF_MOCK_OUTPUT</value>
		</constructor-arg>
	</bean>
</beans>

到这里,所有的代码和配置文件就都整好了,下面就是进行测试,测试代码如下:

  1. 生产者测试代码:  
  2. package com.chhliu.myself.activemq.start.sync;  
  3.   
  4. import javax.annotation.Resource;  
  5. import javax.jms.Destination;  
  6.   
  7. import org.junit.Test;  
  8. import org.junit.runner.RunWith;  
  9. import org.springframework.test.context.ContextConfiguration;  
  10. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  11.   
  12. @RunWith(SpringJUnit4ClassRunner.class)  
  13. @ContextConfiguration(locations = { "classpath:applicationContext.xml" })  
  14. public class SyncProducerActiveMQTest {  
  15.       
  16.     @Resource(name="producerServiceImpl")  
  17.     private ProducerService pService;  
  18.       
  19.     @Resource(name="queueDestination")  
  20.     private Destination receiveQueue;  
  21.       
  22.     @Test  
  23.     public void producerTest(){  
  24.         pService.sendMessage(receiveQueue, "my name is chhliu!");  
  25.     }  
  26. }  
  27.   
  28. 消费者测试代码:  
  29. package com.chhliu.myself.activemq.start.sync;  
  30.   
  31. import javax.annotation.Resource;  
  32. import javax.jms.Destination;  
  33.   
  34. import org.junit.Test;  
  35. import org.junit.runner.RunWith;  
  36. import org.springframework.test.context.ContextConfiguration;  
  37. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  38.   
  39. @RunWith(SpringJUnit4ClassRunner.class)  
  40. @ContextConfiguration(locations = { "classpath:applicationContext.xml" })  
  41. public class SyncConsumerActiveMQTest {  
  42.       
  43.     @Resource(name="consumerServiceImpl")  
  44.     private ConsumerService cService;  
  45.       
  46.     @Resource(name="queueDestination")  
  47.     private Destination receiveQueue;  
  48.       
  49.     @Resource(name="responseQueue")  
  50.     private Destination replyQueue;  
  51.       
  52.     @Test  
  53.     public void producerTest(){  
  54.         String result = cService.receiveMessage(receiveQueue, replyQueue);  
  55.         System.out.println(result);  
  56.     }  
  57. }  
生产者测试代码:
package com.chhliu.myself.activemq.start.sync;

import javax.annotation.Resource;
import javax.jms.Destination;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class SyncProducerActiveMQTest {
	
	@Resource(name="producerServiceImpl")
	private ProducerService pService;
	
	@Resource(name="queueDestination")
	private Destination receiveQueue;
	
	@Test
	public void producerTest(){
        pService.sendMessage(receiveQueue, "my name is chhliu!");
	}
}

消费者测试代码:
package com.chhliu.myself.activemq.start.sync;

import javax.annotation.Resource;
import javax.jms.Destination;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class SyncConsumerActiveMQTest {
	
	@Resource(name="consumerServiceImpl")
	private ConsumerService cService;
	
	@Resource(name="queueDestination")
	private Destination receiveQueue;
	
	@Resource(name="responseQueue")
	private Destination replyQueue;
	
	@Test
	public void producerTest(){
		String result = cService.receiveMessage(receiveQueue, replyQueue);
		System.out.println(result);
	}
}
测试结果如下:

  1. <span style="background-color: rgb(51, 255, 51);">生产者测试结果:  
  2. ================生产者创建了一条消息==============  
  3. 消费者测试结果:  
  4. 收到生产者的消息:hello acticeMQ:my name is chhliu!  
  5. hello acticeMQ:my name is chhliu!</span>  
<span style="background-color: rgb(51, 255, 51);">生产者测试结果:
================生产者创建了一条消息==============
消费者测试结果:
收到生产者的消息:hello acticeMQ:my name is chhliu!
hello acticeMQ:my name is chhliu!</span>

再来看下ActiveMQ的管理页面的结果:

从管理页面中可以看到,生产者生产了消息,并且入队列了,同时消费者也消费了消息,并将回复消息放到了回复队列中,测试成功。

但是这种同步取消息的方式有个缺点,每次只会取一条消息消费,取完之后就会一直阻塞,下面来测试一下:首先让生产者再生产5条消息,然后运行消费者程序,发现会只消费一条消息,除非我们在消费者程序里面加while(true),一直轮询队列,这种实现方式不仅耗内存,效率也不是很高,后面,我们会对这种方式进行改进,使用异步监听模式,测试效果如下:

生产者创建了5条消息:

=======生产者创建了一条消息========

=======生产者创建了一条消息========

=======生产者创建了一条消息========

=======生产者创建了一条消息========

======生产者创建了一条消息=========

ActiveMQ管理页面如下:

消费者消费一条消息:

收到生产者的消息:hello acticeMQ:my name is chhliu!

hello acticeMQ:my name is chhliu!

消费者消费消息后,ActiveMQ管理页面如下:

从上面的对比中,我们可以看出来,同步模式下,消费者消费消息时,是逐条消费,每次只消费一条消息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值