以ActiveMQ为例JAVA消息中间件学习【2】
前言
之前我们学习了什么是消息中间件,以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】的更多相关文章
- 以ActiveMQ为例JAVA消息中间件学习【1】
		
前言 在慢慢的接触大型的javaweb的项目就会接触到很多的中间件系统. 其中消息中间件在很多场景下会被运用. 这里主要就对最近所学习到的消息中间件知识做一个笔记,为以后的实际运用打下一个良好的基础. ...
 - 以ActiveMQ为例JAVA消息中间件学习【4】——消息中间件实际应用场景
		
前言 当前真正学习消息中间件,当前已经走到了,可以简单的使用,网上有很多那种复杂的高可用的架构,但是那些都是对于一些比较大型的项目来说的. 对于一些小型的项目可能用不到那么大的架构,于是我们需要从最简 ...
 - 以ActiveMQ为例JAVA消息中间件学习【3】——SpringBoot中使用ActiveMQ
		
前言 首先我们在java环境中使用了ActiveMQ,然后我们又在Spring中使用了ActiveMQ 本来这样已经可以了,但是最近SpringBoot也来了.所以在其中也需要使用试试. 可以提前透露 ...
 - Java消息中间件入门笔记 - ActiveMQ篇
		
入门 消息中间件带来的好处: 1)解耦:系统解耦 2)异步:异步执行 3)横向扩展 4)安全可靠 5)顺序保证 栗子: 通过服务调用让其它系统感知事件发生 系统之间高耦合 程序执行效率低 通过消息中间 ...
 - java消息中间件之ActiveMQ初识
		
目录 消息中间件简介 解耦合和异步 可靠性和高效性 JMS P2P Pub/Sub AMQP JMS和AMQP对比 常见消息中间件 ActiveMQ RabbitMQ Kafka 综合比较 标签(空格 ...
 - Java工程师学习指南 完结篇
		
Java工程师学习指南 完结篇 先声明一点,文章里面不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦. 因为笔者还只是一名在校 ...
 - Java工程师学习指南(完结篇)
		
Java工程师学习指南 完结篇 先声明一点,文章里面不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦. 因为笔者还只是一名在校 ...
 - Java多线程学习笔记
		
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
 - Java Web学习系列——Maven Web项目中集成使用Spring
		
参考Java Web学习系列——创建基于Maven的Web项目一文,创建一个名为LockMIS的Maven Web项目. 添加依赖Jar包 推荐在http://mvnrepository.com/.h ...
 
随机推荐
- 拿来主义:treeview插件父子节点问题
			
鄙人公司没有专门的前端,所以项目开发中都是前后端一起抡.最近用bootstrap用的比较频繁,发现bootstrap除了框架本身的样式组件外,还提供了多种插件供开发者选择.本篇博文讲的就是bootst ...
 - webapi 重复提交问题
			
https://izen.live/Blog/info/13.html /// <summary> /// action方法过滤器 /// </summary> public ...
 - Linux module 添加到bashrc 和临时ifort编译器 以及python2和3的配置
			
第一步vim ~/.bashrc按键盘的i然后source /home/export/online1/bjpara/para/modules/scripts/cn-module.sh最后:x! bas ...
 - linux debian 9  / centos 7配置postgresSQL数据库
			
#读者注意:本文可以选择不看解释,直接执行每段的0中的代码 (〇):一些概念(可以跳过直接使用(一)0的代码) 1. 客户端:psql.postgreSQL的命令行客户端程序,在终端输入psql进入p ...
 - ABP框架系列之八:(Introduction-介绍)
			
Introduction We are creating different applications based on different needs. But implementing commo ...
 - Python开发——4.集合和字符串拼接
			
一.集合(set) 1.集合的特性: 不同元素组成.元素是无序排列的可hash值 2.集合转为列表 s1 = {11,"hechouzi",(11,22,33)} names = ...
 - 11-22 ArrayList
			
自己定义一个类 public class Student{ public String name; //属性 public void fangfa(){ //方法 } } 在另一个java文件里可以调 ...
 - java基础-位运算符
			
1.位运算符 << 左移 : 右边以0填充 >> 带符号右移: 负数前面补1,整数补0 >>>不带符号右移 & 按位与运算 ...
 - Android Studio中的大量findViewById
			
一. 分析 在Android Studio中开发时,findViewById是用的最多的函数之一.经常需要对返回的view进行类型转换,输入麻烦.代码丑陋. 本文提供两种方案来解决这个问题: 1.安装 ...
 - 《Node.js 高级编程》简介与第二章笔记
			
<Node.js 高级编程> 作者简介 Pedro Teixerra 高产,开源项目程序员 Node 社区活跃成员,Node公司的创始人之一. 10岁开始编程,Visual Basic.C ...