前言

之前我们学习了什么是消息中间件,以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. HashMap的tableSizeFor方法解读

    static final int tableSizeFor(int cap) { int n = cap - 1; n |= n >>> 1; n |= n >>> ...

  2. IOS Javascript Date的坑

    Date对象是JavaScript提供的日期和时间的操作接口,它有多种用法.手册上或者网上也有很多文章介绍,这里就不再次复述了. 上次遇到一个坑,这里总结下,也不是什么大问题,若是如果有经验,就不会花 ...

  3. 提交操作自动遮蔽实现之ajax

    有时候,我们期望一些提交操作自动增加遮蔽效果,提交成功时自动去除遮蔽. 方案: 1. 提交前增加遮蔽逻辑,成功后增加去除遮蔽逻辑,但是不够智能 2.通过ajax拦截,实现自动添加\去除遮蔽效果 aja ...

  4. [uboot] (第二章)uboot流程——uboot-spl编译流程

    http://blog.csdn.net/ooonebook/article/details/52949584 以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为 ...

  5. SAS对数据变量的处理

    SAS对数据变量的处理 在使用DATA步基于已经存在的数据集生成新数据集时,可以指定在新数据集中不需要包含的变量而仅读取其他变量,或者指定仅需要在 新数据集中包含的变量.该功能可以通过DATA步中的S ...

  6. 解决刚刚安装完mysql 远程连接不上问题

    解决远程连接mysql错误1130 远程连接Mysql服务器的数据库,错误代码是1130,ERROR 1130: Host xxx.xxx.xxx.xxx  is not allowed to con ...

  7. 结构体struct、联合体union、枚举类型enum

    1.c语言中的类型 1)内置类型——char,short,int,float,double: 2)用户自定义类型(UDT)——struct结构体,union联合体,enum枚举类型 2.内存对齐 2. ...

  8. Linux下强制杀死进程的方法

    常规篇: 首先,用ps查看进程,方法如下: $ ps -ef …… smx 1822 1 0 11:38 ? 00:00:49 gnome-terminal smx 1823 1822 0 11:38 ...

  9. qhfl-2 ContentType组件

    一般商城里有很多的商品,计优惠券对应着活动类型商品,家电是一类商品,食物是一类商品,优惠券对应着不同的商品类别. from django.db import models class Applianc ...

  10. BASH 正则表达式和文本处理工具

    本节内容 1.  什么是正则 2.  grep 3.  sed 4.  awk 5.  其他补充 一  什么是正则 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方 ...