zoukankan      html  css  js  c++  java
  • SpringBoot实战(十一)之与JMS简单通信

    什么是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使用基于缓存的连接工厂,这样您就可以异步使用消息并以最大的连接效率。

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

  • 相关阅读:
    SCAU 9504 面试
    SCAU 9503 懒人选座位
    SCAU 8628 相亲
    SCAU 10691 ACM 光环
    SCAU 8626 原子量计数
    SCAU 10674 等差对
    HDU ACM 1048 The Hardest Problem Ever (水题)
    SCAU 9502 ARDF
    SCAU 10686 DeathGod不知道的事情
    SCAU 8629 热身游戏(高精度)
  • 原文地址:https://www.cnblogs.com/youcong/p/9409694.html
Copyright © 2011-2022 走看看