前言

之前我们学习了什么是消息中间件,以ActiveMQ为例做了一个最简单的消息中间件的实现。但是我们做的就只能算是个例子而已,因为在实际的项目中肯定会有spring插一脚,所以spring肯定有来管理,所以这次我们就来学习spring中如何使用ActiveMQ

创建消息发送者

导入依赖

<dependencies>
<!--junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--springContext-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<!--spring和jms-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<!--springTest-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<!--activeMQ,排除spring-context-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

配置spring配置文件

<?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"
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"> <!--启用注解-->
<context:annotation-config/>
<context:component-scan base-package="com.xex.springActivemq"/> <!--ActiveMQ为我们提供的ConnectionFactory-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://127.0.0.1:61616" />
</bean> <!--spring jms为我们提供的连接池-->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean> <!--一个队列模式的目的地-->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue-test"/>
</bean> <!--jmsTemplate-->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
</bean> </beans>

定义一个发送消息服务的接口

/**
* 发送消息服务接口
*/
public interface IProducerService {
void sendMessage(String message);
}

定义这个接口的实现类

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.annotation.Resource;
import javax.jms.*; /**
* 发送消息接口的实现
*/
@Service("producerService")
public class ProducerServiceImpl implements IProducerService {
@Autowired
JmsTemplate jmsTemplate; @Resource(name="queueDestination")
Destination destination; public void sendMessage(final String message) {
jmsTemplate.send(destination, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
TextMessage textMessage = session.createTextMessage(message);
System.out.println("发送的消息是:" + textMessage.getText());
return textMessage;
}
});
}
}

编写单元测试

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /**
* ActiveMQ单元测试
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:producer.xml"})
public class IProducerServiceTest { @Autowired
private ProducerServiceImpl producerService; @Test
public void sendMessage() throws Exception {
producerService.sendMessage("测试");
} }

记得测试之前开启ActiveMQ哦

然后查看消息队列是否被创建

创建消息的消费者

创建监听器

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage; /**
* 消息的消费者(监听器)
*/
public class ConsumerMessageListener implements MessageListener {
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("接收到消息:" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}

创建消费者的spring配置

<?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为我们提供的ConnectionFactory-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://127.0.0.1:61616" />
</bean> <!--spring jms为我们提供的连接池-->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean> <!--一个队列模式的目的地-->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue-test"/>
</bean> <!--监听器-->
<bean id="consumerMessageListener" class="com.xex.springActivemq.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>

创建消费者的单元测试

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:consumer.xml"})
public class ConsumerMessageListenerTest {
@Test
public void onMessage() throws Exception {
//让线程等待一会,如果马上结束就监听器就收不到消息了
Thread.sleep(100000);
}
}

然后启动单元测试

接收到消息:测试

证明已经消费掉我们刚才的消息了

主题模式

上面是使用的队列模式,那么主题模式需要修改那些地方呢?三个地方

在队列模式的目的地下方增加主题模式目的地,注意消费者的spring配置和发送消息的配置文件都需要修改哦

<!--一个队列模式的目的地-->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue-test"/>
</bean> <!--主题模式的目的地-->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="topic-test"/>
</bean>

修改消费者spring配置中监听容器的配置

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

修改消息发送者实现类

@Resource(name="queueDestination")
Destination destination;
@Resource(name="topicDestination")
Destination destination;
 

到这里所有对于主题模式的修改就可以了,然后先启动订阅者,然后在启动消息的发送者,这次我们多发一条消息试试第一个订阅者

接收到消息:测试1
接收到消息:测试2

第二个订阅者

接收到消息:测试1
接收到消息:测试2

总结

以上我们就基本实现了在spring下使用ActiveMQ

但是代码和配置上面当然还需要优化和提炼,还有公共的部分可以提取,然后命名修改一下,然后根据具体的业务去设计接口等。

之后我们还会再详细的说明

以ActiveMQ为例JAVA消息中间件学习【2】的更多相关文章

  1. 以ActiveMQ为例JAVA消息中间件学习【1】

    前言 在慢慢的接触大型的javaweb的项目就会接触到很多的中间件系统. 其中消息中间件在很多场景下会被运用. 这里主要就对最近所学习到的消息中间件知识做一个笔记,为以后的实际运用打下一个良好的基础. ...

  2. 以ActiveMQ为例JAVA消息中间件学习【4】——消息中间件实际应用场景

    前言 当前真正学习消息中间件,当前已经走到了,可以简单的使用,网上有很多那种复杂的高可用的架构,但是那些都是对于一些比较大型的项目来说的. 对于一些小型的项目可能用不到那么大的架构,于是我们需要从最简 ...

  3. 以ActiveMQ为例JAVA消息中间件学习【3】——SpringBoot中使用ActiveMQ

    前言 首先我们在java环境中使用了ActiveMQ,然后我们又在Spring中使用了ActiveMQ 本来这样已经可以了,但是最近SpringBoot也来了.所以在其中也需要使用试试. 可以提前透露 ...

  4. Java消息中间件入门笔记 - ActiveMQ篇

    入门 消息中间件带来的好处: 1)解耦:系统解耦 2)异步:异步执行 3)横向扩展 4)安全可靠 5)顺序保证 栗子: 通过服务调用让其它系统感知事件发生 系统之间高耦合 程序执行效率低 通过消息中间 ...

  5. java消息中间件之ActiveMQ初识

    目录 消息中间件简介 解耦合和异步 可靠性和高效性 JMS P2P Pub/Sub AMQP JMS和AMQP对比 常见消息中间件 ActiveMQ RabbitMQ Kafka 综合比较 标签(空格 ...

  6. Java工程师学习指南 完结篇

    Java工程师学习指南 完结篇 先声明一点,文章里面不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦. 因为笔者还只是一名在校 ...

  7. Java工程师学习指南(完结篇)

    Java工程师学习指南 完结篇 先声明一点,文章里面不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦. 因为笔者还只是一名在校 ...

  8. Java多线程学习笔记

    进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...

  9. Java Web学习系列——Maven Web项目中集成使用Spring

    参考Java Web学习系列——创建基于Maven的Web项目一文,创建一个名为LockMIS的Maven Web项目. 添加依赖Jar包 推荐在http://mvnrepository.com/.h ...

随机推荐

  1. java编译时出现——注:使用了未经检查或不安全的操作。注:有关详细信息,请使用 -Xlint:unchecked 重新编译

    网上说是泛型问题 private List<Product> products = new ArrayList<Product>(); 这种用法绝对没错!(因为是照着书写的)在 ...

  2. ramfs的两种制作方法

    制作方法1 1  准备一个已经可以使用的文件系统,假设目录为/rootfsLinux内核需要支持ext2文件系统及ramdisk支持(fs相应的选项要勾上)2 在pc上制作ramdisk镜像(1)dd ...

  3. RNA测序的质量控制

    RNA测序的质量控制 发表评论 3,112 A+ 所属分类:Transcriptomics   收  藏 ENCODE项目向我们揭示,人类基因组中超过70%能得到转录,只不过不会发生在同一个细胞里.为 ...

  4. trinitycore 魔兽服务器源码分析(一) 网络

    trinitycore是游戏服务器的开源代码 许多玩家使用魔兽的数据来进行测试 ,使用它来假设魔兽私服. 官方网址  https://www.trinitycore.org/ 类似的还有mangos ...

  5. xbee/xbeeRPOS1、xbee/xbeePROS2C802.15.4/Digimesh功能方法

    Digi XBee 802.15.4的第一个版本也称为S1,是基于Freescale的无线收发器片子设计的.最新的802.15.4模块(内部称号S1B)采用和Digi ZigBee模块相同SOC芯片设 ...

  6. ABP框架系列之四十九:(Startup-Configuration-启动配置)

    ASP.NET Boilerplate provides an infrastructure and a model to configure it and modules on startup. A ...

  7. collection管理程序中不同类别的资源

    在一个计算图中,可以通过collection管理不同类别的资源,如通过tf.add_to_collection函数可以将资源加入一个或多个集合中,然后通过tf.get_collection获取一个集合 ...

  8. [预打印]使用vbs给PPT(包括公式)去背景

    原先博客放弃使用,几篇文章搬运过来 在 视图—>宏 内新建宏 '终极版 Sub ReColor() Dim sld As Slide Dim sh As Shape For Each sld I ...

  9. $q的基本用法

    angularjs的http是异步的没有同步,一般都会遇到一个场景,会把异步请求的参数作为条件执行下一个函数,之前一直在看其他人的博客理论太多看了很久才看懂 http({ method:'post', ...

  10. Vuejs——(4)v-if、v-for

    版权声明:出处http://blog.csdn.net/qq20004604   目录(?)[+]   (二十)v-if ①标准v-if用法 简单来说,该值为true则显示该标签,为false则不显示 ...