什么是JMS?

引用百度百科上的说明:

JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。
JMS是一种与厂商无关的 API,用来访问消息收发系统消息,它类似于JDBC(Java Database Connectivity)。这里,JDBC 是可以用来访问许多不同关系数据库的 API,而 JMS 则提供同样与厂商无关的访问方法,以访问消息收发服务。许多厂商都支持 JMS,包括 IBM 的 MQSeries、BEA的 Weblogic JMS service和 Progress 的 SonicMQ。 JMS 使您能够通过消息收发服务(有时称为消息中介程序或路由器)从一个 JMS 客户机向另一个 JMS客户机发送消息。消息是 JMS 中的一种类型对象,由两部分组成:报头和消息主体。报头由路由信息以及有关该消息的元数据组成。消息主体则携带着应用程序的数据或有效负载。根据有效负载的类型来划分,可以将消息分为几种类型,它们分别携带:简单文本(TextMessage)、可序列化的对象 (ObjectMessage)、属性集合 (MapMessage)、字节流 (BytesMessage)、原始值流 (StreamMessage),还有无有效负载的消息 (Message)。
 
下面进入SpringBoot简单使用JMS示例:
 
一、导入依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5.  
  6. <groupId>org.springframework</groupId>
  7. <artifactId>gs-messaging-jms</artifactId>
  8. <version>0.1.0</version>
  9.  
  10. <parent>
  11. <groupId>org.springframework.boot</groupId>
  12. <artifactId>spring-boot-starter-parent</artifactId>
  13. <version>1.5.8.RELEASE</version>
  14. </parent>
  15.  
  16. <properties>
  17. <java.version>1.8</java.version>
  18. </properties>
  19.  
  20. <dependencies>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-activemq</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.apache.activemq</groupId>
  27. <artifactId>activemq-broker</artifactId>
  28. </dependency>
  29.  
  30. <dependency>
  31. <groupId>com.fasterxml.jackson.core</groupId>
  32. <artifactId>jackson-databind</artifactId>
  33. </dependency>
  34. </dependencies>
  35.  
  36. <build>
  37. <plugins>
  38. <plugin>
  39. <groupId>org.springframework.boot</groupId>
  40. <artifactId>spring-boot-maven-plugin</artifactId>
  41. </plugin>
  42. </plugins>
  43. </build>
  44.  
  45. </project>

二、编写消息接收器

  1. package hello;
  2.  
  3. public class Email {
  4.  
  5. private String to;
  6. private String body;
  7.  
  8. public Email() {
  9. }
  10.  
  11. public Email(String to, String body) {
  12. this.to = to;
  13. this.body = body;
  14. }
  15.  
  16. public String getTo() {
  17. return to;
  18. }
  19.  
  20. public void setTo(String to) {
  21. this.to = to;
  22. }
  23.  
  24. public String getBody() {
  25. return body;
  26. }
  27.  
  28. public void setBody(String body) {
  29. this.body = body;
  30. }
  31.  
  32. @Override
  33. public String toString() {
  34. return String.format("Email{to=%s, body=%s}", getTo(), getBody());
  35. }
  36.  
  37. }

三、定义消息接收者

  1. package hello;
  2.  
  3. import org.springframework.jms.annotation.JmsListener;
  4. import org.springframework.stereotype.Component;
  5.  
  6. @Component
  7. public class Receiver {
  8.  
  9. @JmsListener(destination = "mailbox", containerFactory = "myFactory")
  10. public void receiveMessage(Email email) {
  11. System.out.println("Received <" + email + ">");
  12. }
  13.  
  14. }

Receiver也被称为消息驱动的POJO。正如您在上面的代码中所看到的,不需要实现任何特定的接口或方法具有任何特定的名称。此外,该方法可以具有非常灵活的签名。请特别注意,此类在JMS API上没有导入。

四、使用Spring发送和接收JMS消息

  1. package hello;
  2.  
  3. import javax.jms.ConnectionFactory;
  4.  
  5. import org.springframework.boot.SpringApplication;
  6. import org.springframework.boot.autoconfigure.SpringBootApplication;
  7. import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
  8. import org.springframework.context.ConfigurableApplicationContext;
  9. import org.springframework.context.annotation.Bean;
  10. import org.springframework.jms.annotation.EnableJms;
  11. import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
  12. import org.springframework.jms.config.JmsListenerContainerFactory;
  13. import org.springframework.jms.core.JmsTemplate;
  14. import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
  15. import org.springframework.jms.support.converter.MessageConverter;
  16. import org.springframework.jms.support.converter.MessageType;
  17.  
  18. @SpringBootApplication
  19. @EnableJms
  20. public class Application {
  21.  
  22. @Bean
  23. public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
  24. DefaultJmsListenerContainerFactoryConfigurer configurer) {
  25. DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
  26. // This provides all boot's default to this factory, including the message converter
  27. configurer.configure(factory, connectionFactory);
  28. // You could still override some of Boot's default if necessary.
  29. return factory;
  30. }
  31.  
  32. @Bean // Serialize message content to json using TextMessage
  33. public MessageConverter jacksonJmsMessageConverter() {
  34. MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
  35. converter.setTargetType(MessageType.TEXT);
  36. converter.setTypeIdPropertyName("_type");
  37. return converter;
  38. }
  39.  
  40. public static void main(String[] args) {
  41. // Launch the application
  42. ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
  43.  
  44. JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
  45.  
  46. // Send a message with a POJO - the template reuse the message converter
  47. System.out.println("Sending an email message.");
  48. jmsTemplate.convertAndSend("mailbox", new Email("info@example.com", "Hello"));
  49. }
  50.  
  51. }

@Bean注解,主要作用是控制反转(IOC),同

<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
    </bean>

举例说明:

例如以Message为例:

  1. @Bean
  2. public String message() {
  3. return new String("hello");
  4. }

它等价于

  1. <bean id="message" class="java.lang.String">
  2. <constructor-arg index="0" value="hello"/>
  3. </bean>

通常情况下,有三种配置Bean的方式:

如图所示

关于Bean注解三种配置法,深入介绍可以参考该博文:https://blog.csdn.net/icarus_wang/article/details/51649635

@EnableJms 触发发现带注释的方法@JmsListener,在封面下创建消息监听器容器。

为清楚起见,我们还定义了一个在接收器注释中myFactory引用的bean JmsListener。因为我们使用DefaultJmsListenerContainerFactoryConfigurerSpring Boot提供的基础结构,所以JmsMessageListenerContainer它与默认情况下引导创建的基础结构相同。

默认MessageConverter是能够转换只有基本类型(例如StringMapSerializable)我们Email是不是Serializable故意的。我们想要使用Jackson并以文本格式将内容序列化为json(即作为a TextMessage)。Spring Boot将检测a的存在,MessageConverter并将其与默认值JmsTemplate和任何JmsListenerContainerFactory创建者相关联DefaultJmsListenerContainerFactoryConfigurer

JmsTemplate使消息发送到JMS目的地变得非常简单。在mainrunner方法中,启动后,您可以使用jmsTemplate发送EmailPOJO。因为我们的自定义MessageConverter已自动关联到它,所以只会生成一个json文档TextMessage

你没看到的两个bean是JmsTemplateConnectionFactory。这些是由Spring Boot自动创建的。在这种情况下,ActiveMQ代理运行嵌入式。

注意:

Spring JmsTemplate可以通过它的receive方法直接接收消息,但这只能同步工作,这意味着它会阻塞。这就是为什么我们建议您使用侦听器容器,例如DefaultMessageListenerContainer使用基于缓存的连接工厂,这样您就可以异步使用消息并以最大的连接效率。

最后运行结果如下图所示:

SpringBoot实战(十一)之与JMS简单通信的更多相关文章

  1. springboot实战开发全套教程,让开发像搭积木一样简单!Github星标已上10W+!

    前言 先说一下,这份教程在github上面星标已上10W,下面我会一一给大家举例出来全部内容,原链接后面我会发出来!首先我讲一下接下来我们会讲到的知识和技术,对比讲解了多种同类技术的使用手日区别,大家 ...

  2. SpringBoot实战 之 异常处理篇

    在互联网时代,我们所开发的应用大多是直面用户的,程序中的任何一点小疏忽都可能导致用户的流失,而程序出现异常往往又是不可避免的,那该如何减少程序异常对用户体验的影响呢?其实方法很简单,对异常进行捕获,然 ...

  3. apollo客户端springboot实战(四)

    1. apollo客户端springboot实战(四) 1.1. 前言   经过前几张入门学习,基本已经完成了apollo环境的搭建和简单客户端例子,但我们现在流行的通常是springboot的客户端 ...

  4. SpringBoot实战(四)获取接口请求中的参数(@PathVariable,@RequestParam,@RequestBody)

    上一篇SpringBoot实战(二)Restful风格API接口中写了一个控制器,获取了前端请求的参数,现在我们就参数的获取与校验做一个介绍: 一:获取参数 SpringBoot提供的获取参数注解包括 ...

  5. SpringBoot实战(二)Restful风格API接口

    在上一篇SpringBoot实战(一)HelloWorld的基础上,编写一个Restful风格的API接口: 1.根据MVC原则,创建一个简单的目录结构,包括controller和entity,分别创 ...

  6. JMS消息通信服务

    什么是Java消息服务 Java消息服务指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建.发送.读取消息等,用于支持JAVA应用程序开发.在J2EE中 ...

  7. SpringBoot实战之异常处理篇

    在互联网时代,我们所开发的应用大多是直面用户的,程序中的任何一点小疏忽都可能导致用户的流失,而程序出现异常往往又是不可避免的,那该如何减少程序异常对用户体验的影响呢?其实方法很简单,对异常进行捕获,然 ...

  8. Docker深入浅出系列 | 单机Nginx+Springboot实战

    目录 Nginx+Springboot实战 前期准备 实战目标 实战步骤 创建Docker网络 搭建Mysql容器 搭建额度服务集群 搭建Nginx服务 验证额度服务 附录 Nginx+Springb ...

  9. Eclipse搭建服务器,实现与Android的简单通信

    ---恢复内容开始--- 目标:实现客户端(Android App)与服务器(PC)的简单通信 相关准备:eclipse_mars.tomcat8.Android Studio 实现: 1.java环 ...

随机推荐

  1. static关键字作用

    之前讲到final关键字的作用是每次面试的时候我必问求职者的两个问题之一,另外一个问题就是文本会写到的static.final和static一样,都是一个小问题可以看到一个人的基础是否扎实以及平时是否 ...

  2. shell条件测试和流程控制

    一.条件测试操作 1.test 用途:测试特定的表达式是否成立,当条件成立时,命令执行后的返回值为0,否则为其他数值 格式:test 表达式 2.常见的测试类型 ①测试文件状态 格式:[ 操作符 文件 ...

  3. ARP原理和欺骗

    ARP--在TCP/IP协议栈中,最不安全的协议莫过于ARP了,我们经常听到的网络扫描,内网***,流量欺骗等等,他们基本上都与ARP有关系,甚至可以说,他们的底层都是基于ARP实现的.但是ARP的是 ...

  4. Eclipse3.2查找jre的问题

    前几天遇到一个问题,最开始电脑上使用的是解压的JDK(带jre),但是不能打开jar文件.所以从网上下载了一个jre1.8,然后问题来了,Eclipse打开就报错,弹出一个框,在eclipse的目录下 ...

  5. Linux上把新磁盘扩展到已有分区中(基于LVM)

    0.在不重启服务器的前提下找到新加的磁盘 --查看主机总线号 ls /sys/class/scsi_host/ --根据查询结果生成刷新磁盘语句 echo "- - -" > ...

  6. CF891E Lust

    传送门 题目大意 你有 \(n\) 个数 \(a_1,a_2...a_n\) 要进行 \(k\) 次操作 每次随机选择一个数 \(x\),使得答案加上 \(\prod_{i \neq x}a_i\) ...

  7. 微信小程序开发7-JavaScript脚本

    1.小程序的主要开发语言是 JavaScript ,开发者使用 JavaScript 来开发业务逻辑以及调用小程序的 API 来完成业务需求. 2.ECMAScript 在大部分开发者看来,ECMAS ...

  8. JS计算距当前时间的时间差

    /** * JS获取距当前时间差 * * @param int time JS毫秒时间戳 * */ function get_time_diff(time) { var diff = ''; var ...

  9. SQL SERVER占用CPU过高优化S

    https://www.cnblogs.com/yuekong2010/p/6628001.html 然后使用下面语句看一下各项指标是否正常,是否有阻塞,正常情况下搜索结果应该为空. 1 SELECT ...

  10. [转]实现Hive数据同步更新的shell脚本

    引言: 上一篇文章<Sqoop1.4.4 实现将 Oracle10g 中的增量数据导入 Hive0.13.1 ,并更新Hive中的主表>http://www.linuxidc.com/Li ...