前言

之前我们学习了什么是消息中间件,以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. python基础(二)列表与字典

    列表list-数组stus=['苹果','香蕉','橘子','红枣',111.122,]# 下标 0 1 2 3 4#下标,索引,角标#print(stus[4]) #st=[]#空list#st=l ...

  2. vue 关于父组件无法触发子组件的事件的解决方法

    一般情况导致无法触发子组件的方法  基本都是由于子组件未渲染完成 就进行了调用,解决方法如下: 1.加定时器  setTimeout(() => { //加定时器原因是,子组件页面未渲染处理就做 ...

  3. js的一些总结

    函数 函数是一等公民 函数可以有属性,并且能连接到它的构造方法 函数可以像一个变量一样存在内存中 函数可以当做参数传给其他函数 函数可以返回其他函数 加法操作表 Number + Number -&g ...

  4. PHP开发——分支结构

    If if if···else··· if···else··· switch

  5. Django之URL(路由系统)用法

    路由系统 路由系统概念 简而言之,路由系统就是路径和视图函数的一个对应关系.django的路由系统作用就是使views里面处理数据的函数与请求的url建立映射关系.使请求到来之后,根据urls.py里 ...

  6. 服务器重新启动,ftp重新连接问题

    服务器重新启动,发现FlashFXP无法连接了,估计是ftp没有启动, 1. 首先服务器要安装ftp软件,查看是否已经安装ftp软件下:   #which vsftpd   如果看到有vsftpd的目 ...

  7. Java第五次实验

    Java第五次实验--网络编程与安全 任务一: 一.实验要求: 两人一组结对编程: 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA 结对实现 ...

  8. 深入理解JVM(一)编译openJDK

    此文总结的很不错:https://www.cnblogs.com/ACFLOOD/p/5528035.html 准备openJDK源码和环境 1.在linux和macOS上编译openJDK更加友好, ...

  9. 第六次spring会议

    昨天所做之事: 我对软件加上了保密功能. 今天所做内容: 我对软件加上了一键解密功能. private void 一键还原ToolStripMenuItem_Click(object sender, ...

  10. Maven学习 一 概念介绍

    一 Maven是什么 Maven是一个Apache公司的开源项目,主要有两个作用:(1)是项目构建工具.(2)是用来管理java程序中jar包的依赖. 它包含了一个项目对象模型(Project Obj ...