您现在的位置是:首页 > 文章详情

SpringBoot实战(十一)之与JMS简单通信

日期:2018-08-02点击:499

什么是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示例:
 
一、导入依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.springframework</groupId> <artifactId>gs-messaging-jms</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.8.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-broker</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

 

二、编写消息接收器

package hello;  public class Email { private String to;  private String body;  public Email() { } public Email(String to, String body) { this.to = to;  this.body = body;  } public String getTo() { return to;  } public void setTo(String to) { this.to = to;  } public String getBody() { return body;  } public void setBody(String body) { this.body = body;  } @Override public String toString() { return String.format("Email{to=%s, body=%s}", getTo(), getBody());  } }

 

三、定义消息接收者

package hello; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; @Component public class Receiver { @JmsListener(destination = "mailbox", containerFactory = "myFactory") public void receiveMessage(Email email) { System.out.println("Received <" + email + ">"); } }

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

 

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

package hello; import javax.jms.ConnectionFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.jms.annotation.EnableJms; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.JmsListenerContainerFactory; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.support.converter.MappingJackson2MessageConverter; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.converter.MessageType; @SpringBootApplication @EnableJms public class Application { @Bean public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); // This provides all boot's default to this factory, including the message converter  configurer.configure(factory, connectionFactory); // You could still override some of Boot's default if necessary. return factory; } @Bean // Serialize message content to json using TextMessage public MessageConverter jacksonJmsMessageConverter() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); converter.setTargetType(MessageType.TEXT); converter.setTypeIdPropertyName("_type"); return converter; } public static void main(String[] args) { // Launch the application ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class); // Send a message with a POJO - the template reuse the message converter System.out.println("Sending an email message."); jmsTemplate.convertAndSend("mailbox", new Email("info@example.com", "Hello")); } }

 

 

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

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

举例说明:

例如以Message为例:

 

@Bean public String message() { return new String("hello"); }

 

它等价于

<bean id="message" class="java.lang.String"> <constructor-arg index="0" value="hello"/> </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使用基于缓存的连接工厂,这样您就可以异步使用消息并以最大的连接效率。

 

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

 

原文链接:https://yq.aliyun.com/articles/645123
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章