使用Spring Boot和注释支持配置Spring JMS应用程序

1.简介

在以前的文章中,我们学习了如何使用Spring JMS配置项目。 如果查看有关使用Spring JMS进行消息传递的文章介绍 ,您会注意到它是使用XML配置的。 本文将利用Spring 4.1版本中引入的改进 ,并仅使用Java config来配置JMS项目。

在这个示例中,我们还将看到使用Spring Boot配置项目是多么容易。

在开始之前,请注意,与往常一样,您可以看一下下面示例中使用的项目的源代码。

请参阅github上的示例项目 。

栏目:

  1. 介绍。
  2. 示例应用程序。
  3. 设置项目。
  4. 一个使用JMS侦听器的简单示例。
  5. 使用@SendTo将响应发送到另一个队列。
  6. 结论。

2.示例应用程序

该应用程序使用客户端服务将订单发送到JMS队列,在该队列中将注册JMS侦听器并处理这些订单。 收到后,侦听器将通过Store服务存储订单:

jms_diagram

我们将使用Order类来创建订单:

public class Order implements Serializable {private static final long serialVersionUID = -797586847427389162L;private final String id;public Order(String id) {this.id = id;}public String getId() {return id;}
}

在继续第一个示例之前,我们将首先探讨如何构建项目结构。

3.设置项目

3.1配置pom.xml

首先要做的是将工件spring-boot-starter-parent定义为我们的父pom。

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.2.3.RELEASE</version><relativePath/> <!-- lookup parent from repository -->
</parent>

这个父级基本上设置了几个Maven默认值,并为我们将使用的主要依赖项提供了依赖项管理,例如Spring版本(4.1.6)。

重要的是要注意,此父pom定义了许多库的版本,但未对我们的项目添加任何依赖关系。 因此,不必担心会得到不使用的库。

下一步是设置Spring Boot的基本依赖关系:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>

除了核心Spring库之外,此依赖项还将带来Spring Boot的自动配置功能。 这将允许框架尝试根据您添加的依赖项自动设置配置。

最后,我们将添加Spring JMS依赖项和ActiveMQ消息代理,将整个pom.xml保留如下:

<groupId>xpadro.spring</groupId>
<artifactId>jms-boot-javaconfig</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>JMS Spring Boot Javaconfig</name><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.2.3.RELEASE</version><relativePath/> <!-- lookup parent from repository -->
</parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><start-class>xpadro.spring.jms.JmsJavaconfigApplication</start-class><java.version>1.8</java.version><amq.version>5.4.2</amq.version>
</properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jms</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-core</artifactId><version>${amq.version}</version></dependency>
</dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

3.2使用Java Config进行Spring配置

配置类仅需要配置嵌入式消息代理。 其余的由Spring Boot自动配置:

@SpringBootApplication
public class JmsJavaconfigApplication {private static final String JMS_BROKER_URL = "vm://embedded?broker.persistent=false,useShutdownHook=false";@Beanpublic ConnectionFactory connectionFactory() {return new ActiveMQConnectionFactory(JMS_BROKER_URL);}public static void main(String[] args) {SpringApplication.run(JmsJavaconfigApplication.class, args);}
}

我们使用@SpringBootApplication代替了通常的@Configuration批注。 这个Spring Boot注释也用@Configuration注释。 此外,它还设置其他配置,例如Spring Boot自动配置:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {

现在都设置好了。 在下一部分的示例中,我们将了解如何配置JMS侦听器,因为它已配置了注释。

4.使用JMS侦听器的简单示例

4.1将订单发送到JMS队列

ClientService类负责将新订单发送到JMS队列。 为了做到这一点,它使用一个JmsTemplate:

@Service
public class ClientServiceImpl implements ClientService {private static final String SIMPLE_QUEUE = "simple.queue";private final JmsTemplate jmsTemplate;@Autowiredpublic ClientServiceImpl(JmsTemplate jmsTemplate) {this.jmsTemplate = jmsTemplate;}@Overridepublic void addOrder(Order order) {jmsTemplate.convertAndSend(SIMPLE_QUEUE, order);}
}

在这里,我们使用JmsTemplate转换Order实例并将其发送到JMS队列。 如果您希望直接通过发送消息发送消息,则可以使用新的JmsMessagingTemplate 。 这是更好的选择,因为它使用了更加标准化的Message类。

4.2接收发送到JMS队列的订单

将JMS侦听器注册到JMS侦听器容器就像将@JmsListener批注添加到我们要使用的方法一样简单。 这将在幕后创建一个JMS侦听器容器,该容器将接收发送到指定队列的消息并将它们委派给我们的侦听器类:

@Component
public class SimpleListener {private final StoreService storeService;@Autowiredpublic SimpleListener(StoreService storeService) {this.storeService = storeService;}@JmsListener(destination = "simple.queue")public void receiveOrder(Order order) {storeService.registerOrder(order);}
}

StoreService接收订单并将其保存到已接收订单的列表中:

@Service
public class StoreServiceImpl implements StoreService {private final List<Order> receivedOrders = new ArrayList<>();@Overridepublic void registerOrder(Order order) {this.receivedOrders.add(order);}@Overridepublic Optional<Order> getReceivedOrder(String id) {return receivedOrders.stream().filter(o -> o.getId().equals(id)).findFirst();}
}

4.3测试应用程序

现在让我们添加一个测试来检查我们是否正确完成了所有操作:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = JmsJavaconfigApplication.class)
public class SimpleListenerTest {@Autowiredprivate ClientService clientService;@Autowiredprivate StoreService storeService;@Testpublic void sendSimpleMessage() {clientService.addOrder(new Order("order1"));Optional<Order> storedOrder = storeService.getReceivedOrder("order1");Assert.assertTrue(storedOrder.isPresent());Assert.assertEquals("order1", storedOrder.get().getId());}
}

5.使用@SendTo将响应发送到另一个队列

Spring JMS的另一个附加功能是@SendTo批注。 此批注允许侦听器将消息发送到另一个队列。 例如,以下侦听器从“ in.queue”接收命令,并在存储该命令后向“ out.queue”发送确认。

@JmsListener(destination = "in.queue")
@SendTo("out.queue")
public String receiveOrder(Order order) {storeService.registerOrder(order);return order.getId();
}

在那里,我们注册了另一个侦听器,它将处理此确认ID:

@JmsListener(destination = "out.queue")
public void receiveOrder(String orderId) {registerService.registerOrderId(orderId);
}

六,结论

有了注释支持,现在可以更轻松地配置Spring JMS应用程序,从而利用使用注释JMS侦听器进行异步消息检索的优势。

翻译自: https://www.javacodegeeks.com/2015/04/configure-a-spring-jms-application-with-spring-boot-and-annotation-support.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

两个饥肠咕咕的人

http://www.amznz.com/43/ Long long ago&#xff0c;有两个饥肠咕咕的人得到了一位长者的恩赐&#xff1a;一根鱼竿和一篓鲜活硕大的鱼。其中&#xff0c;一个人要了一篓鱼&#xff0c;另一个人要了一根鱼竿&#xff0c;于是他们分道扬镳了。得到鱼的人原地就用干柴搭起篝火煮…

室内主题元素分析图_2020届室内设计专业优秀毕业设计作品展(五)

“环”食疗养生空间概念设计△建筑外立面▲LOGO前 言每当人们提及健康时&#xff0c;人们的反应往往是运动、睡眠和饮食。现代的青年上班族&#xff0c;又因为快节奏的生活&#xff0c;工作压力大&#xff0c;饮食的不规律&#xff0c;生活不良习性的增加&#xff0c;导致了各…

编写下载服务器。 第一部分:始终流式传输,永远不要完全保留在内存中

下载各种文件&#xff08;文本或二进制文件&#xff09;是每个企业应用程序的生死攸关的事情。 PDF文档&#xff0c;附件&#xff0c;媒体&#xff0c;可执行文件&#xff0c;CSV&#xff0c;超大文件等。几乎每个应用程序迟早都必须提供某种形式的下载。 下载是通过HTTP来实现…

C++输入cin详解

C输入cin详解 输入原理&#xff1a; 程序的输入都建有一个缓冲区&#xff0c;即输入缓冲区。一次输入过程是这样的&#xff0c;当一次键盘输入结束时会将输入的数据存入输入缓冲区&#xff0c;而cin函数直接从输入缓冲区中取数据。正因为cin函数是直接从缓冲区取数据的&#xf…

时间序列的截尾和拖尾_R语言:时间序列(一)

01 解决什么问题在社会活动中经常可见按照时间顺序记录下来的随机事件观察值&#xff0c;例如每年死亡人数序列&#xff0c;每年糖尿病发病人数序列&#xff0c;医院门诊每日诊治病例数序列。这类数据的特性是相邻时间点的观察值之间具有明显的相关性&#xff0c;这一特性不同于…

ulimit小结

1. limits是一个进程的资源&#xff0c;会被子进程继承2. soft limit -S, hard limits -Hhard limits只能被root用户修改&#xff0c;启动的时候会加载配置/etc/security/limits.confsoft limits可以被任何用户修改&#xff0c;但不能超过hard limits3. 在linux下&#xff0c;每…

JVM崩溃时:如何调查最严重错误的根本原因

当应用程序崩溃时&#xff0c;您可以学到什么&#xff1f; 我认为&#xff0c;“后见之明是20 /”是最喜欢的短语之一托马斯罗梅尔 &#xff0c;工程ZeroTurnaround的副总裁。 好吧&#xff0c;我实际上不确定在他的短语中占什么位置&#xff0c;但是我已经听过他几次说了。 鉴…

常用个人密码管理软件

http://www.williamlong.info/archives/3100.html转载于:https://www.cnblogs.com/svennee/p/4099358.html

查看网口命令_20个常用Linux命令

今天总结几个非常常用的Linux命令,其中有几个在面试中很可能问相关命令的原理,比如后台运行命令。希望对大家有所帮助,最好自己去尝试在Linux操作系统中实践一下。 1、查看目录以及权限 在windows中,使用dir查看当前目录中文件。在Linux中使用ls(list)查看当前目录文件。 w…

爱摘苹果的小明

描述小明家的院子里有一棵苹果树&#xff0c;每到秋天树上就会结出10个苹果。苹果成熟的时候&#xff0c;小明就会跑去摘苹果。小明有个30厘米高的板凳&#xff0c;当她不能直接用手摘到苹果的时候&#xff0c;就会踩到板凳上再试试。现在已知10个苹果到地面的高度&#xff0c;…

中统计字符串长度的函数_SQL Server中的字符串分割函数

您是否知道从SQL Server 2016开始&#xff0c;系统就内置STRING_SPLIT函数&#xff0c;该函数用于将字符串分隔的变量拆分为一个可用列表。 对于经常需要分割字符串的技术人员&#xff0c;建议您查看此功能。 STRING_SPLIT是一个表值函数&#xff0c;它返回由定界符分隔的字符串…

JBoss BPM Suite快速指南–将外部数据模型导入BPM项目

您正在从事一个大型项目&#xff0c;在企业中开发规则&#xff0c;事件和流程以满足关键业务需求。 部分要求指出&#xff0c;某个业务部门将提供您的数据模型供您利用。 不会在JBoss BPM Suite数据建模器中设计此数据模型&#xff0c;但是在从业务中心仪表板处理规则&#x…

Android项目笔记【项目管理统计图app】:使用github上的cardslib开源项目实现CardView(1)...

因为项目中用到第三级菜单&#xff0c;我们原有的界面框架已经不适用于该项目&#xff0c;Android L出了新的cardview设计&#xff0c;爬了下github发现有些高手已经把card整合为更方便调用的类库了&#xff0c;我这个项目就准备试用一下其中的一个开源项目cardslib &…

卸载 流程_一款适合于windows端的卸载神器 彻底清理残留软件

今天给大家介绍的是一款适合于Windows端的软件卸载神器---Uninstall&#xff0c;可以彻底清理残留软件。它的卸载流程是这样的&#xff0c;首先会使用软件本身的默认卸载程序进行卸载&#xff0c;卸载完成后再次扫描软件残留的一些残余文件及注册表之类的&#xff0c;可以完美的…

key value vue 输出_vue注意事项总结(一)

1.只有当vue实例被创建时data中存在的属性才是响应式的&#xff1a;如果你知道你会在晚些时候需要一个属性&#xff0c;但是一开始它为空或不存在&#xff0c;那么你仅需要设置一些初始值。2.不要在选项属性或回调上使用箭头函数&#xff1a;比如&#xff1a;created: () > …

netif_start_queue/netif_wake_queue/netif_stop_queue

在网卡驱动中&#xff0c;内核为发送数据包的流量控制提供了几个主要的函数&#xff0c;用来在驱动程序和内核之间传递流控信息。 主要有4个&#xff1a; 1】netif_start_queue 启动接口传输队列 2】netif_wake_queue 通知网络系统可以再次开始传输数据包&#xff1b;并启动接…

编写下载服务器。 第四部分:有效地实现HEAD操作

HEAD是一个经常被遗忘的HTTP方法&#xff08;动词&#xff09;&#xff0c;其行为类似于GET&#xff0c;但不会返回正文。 您使用HEAD来检查资源的存在&#xff08;如果不存在&#xff0c;它应该返回404&#xff09;&#xff0c;并确保您的缓存中没有陈旧的版本。 在这种情况下…

【grunt整合版】30分钟学会使用grunt打包前端代码

http://www.itnose.net/detail/6009394.html转载于:https://www.cnblogs.com/zifeiyu/p/4106585.html

十三水算法php_基于PHP+Redis令牌桶限流

一 、场景描述在开发接口服务器的过程中&#xff0c;为了防止客户端对于接口的滥用&#xff0c;保护服务器的资源&#xff0c; 通常来说我们会对于服务器上的各种接口进行调用次数的限制。比如对于某个 用户&#xff0c;他在一个时间段&#xff08;interval&#xff09;内&…

ECSHOP如何增加红包序列号字符

ECSHOP系统线下发放红包时系统生成的红包序列号是在10000的基础上增加四位随机数字。如果当我们要发放大额度红包的时候&#xff0c;这样的序列号规 则难免给人不安全的感觉&#xff0c;万一有无聊的人&#xff0c;蒙几个红包序列号出来&#xff0c;那就亏大了&#xff0c;因为…