• 20220523 Messaging


    前言

    文档地址

    Spring Framework 为与消息传递系统的集成提供了广泛的支持,从使用 JMS API 的简化使用 JmsTemplate 到异步接收消息的完整基础设施。Spring AMQP 为高级消息队列协议提供了类似的功能集。Spring Boot 还为 RabbitTemplate 和 RabbitMQ 提供了自动配置选项。Spring WebSocket 原生包括对 STOMP 消息传递的支持,Spring Boot 通过启动器和少量的自动配置来支持它。Spring Boot 还支持 Apache Kafka 。

    1. JMS

    javax.jms.ConnectionFactory 接口提供了一种用于创建 javax.jms.Connection 与 JMS 代理进行交互的的标准方法。尽管 Spring 需要 ConnectionFactory 才能与 JMS 一起使用,但是您通常不需要自己直接使用它,而可以依赖于更高级别的消息传递抽象。(有关详细信息,请参见 Spring Framework 参考文档的相关部分。)Spring Boot 还会自动配置必要的基础设施,以发送和接收消息。

    1.1. ActiveMQ 支持

    ActiveMQ 在类路径中可用时,Spring Boot 也可以配置 ConnectionFactory 。如果存在代理,则将自动启动和配置嵌入式代理(前提是未通过配置指定代理 URL,并且未在配置中禁用嵌入式代理)。

    如果使用 spring-boot-starter-activemq ,则提供了连接或嵌入 ActiveMQ 实例所需的必要依赖关系,以及与 JMS 集成的 Spring 基础设施。

    ActiveMQ 配置由 spring.activemq.* 中的外部配置属性控制。

    默认情况下,ActiveMQ 自动配置为使用VM 传输,它启动嵌入在同一 JVM 实例中的代理。

    您可以通过配置 spring.activemq.in-memory 属性来禁用嵌入式代理,如下例所示

    spring.activemq.in-memory=false
    

    如果您配置代理 URL,嵌入式代理也将被禁用,如以下示例所示:

    spring.activemq.broker-url=tcp://192.168.1.210:9876
    spring.activemq.user=admin
    spring.activemq.password=secret
    

    如果您想完全控制嵌入式代理,请参阅 ActiveMQ 文档

    默认情况下,CachingConnectionFactory 用合理的设置包装原生 ConnectionFactory ,您可以通过 spring.jms.* 中的外部配置属性来控制这些设置:

    spring.jms.cache.session-cache-size=5
    

    如果您想使用原生池,则可以通过向其添加依赖项 org.messaginghub:pooled-jms 并对 JmsPoolConnectionFactory 进行相应的配置来实现,如以下示例所示:

    spring.activemq.pool.enabled=true
    spring.activemq.pool.max-connections=50
    

    请参阅 ActiveMQProperties 以获取更多受支持的选项。您还可以注册任意数量的 ActiveMQConnectionFactoryCustomizer Bean ,以实现更高级的自定义。

    默认情况下,如果目标尚不存在,ActiveMQ 会创建一个目的地,以便根据提供的名称解析目的地。

    1.2. ActiveMQ Artemis 支持

    当 Spring Boot 检测到 ActiveMQ Artemis 在类路径中可用时,可以自动配置 ConnectionFactory 。如果存在代理,则将自动启动和配置嵌入式代理(除非已明确设置 mode 属性)。支持的模式是 embedded(明确表示需要嵌入式代理,并且如果代理在类路径上不可用,则会发生错误)和 native(使用 netty 传输协议连接到代理)。配置后者后,Spring Boot 将使用默认设置配置一个 ConnectionFactory 连接到在本地计算机上运行的代理。

    如果使用 spring-boot-starter-artemis ,则提供了连接到现有 ActiveMQ Artemis 实例所需的依赖关系,以及与 JMS 集成的 Spring 基础设施。添加 org.apache.activemq:artemis-jms-server 到您的应用程序可以让您使用嵌入式模式。

    ActiveMQ Artemis 配置由 spring.artemis.* 中的外部配置属性控制。例如,您可以在 application.properties 中声明以下部分:

    spring.artemis.mode=native
    spring.artemis.broker-url=tcp://192.168.1.210:9876
    spring.artemis.user=admin
    spring.artemis.password=secret
    

    嵌入代理时,可以选择是否要启用持久并列出应该可用的目的地。可以将它们指定为以逗号分隔的列表,以使用默认选项创建它们,或者您可以分别为高级队列和主题配置定义类型为 org.apache.activemq.artemis.jms.server.config.JMSQueueConfigurationorg.apache.activemq.artemis.jms.server.config.TopicConfiguration 的 bean 。

    默认情况下,CachingConnectionFactory 用合理的设置包装原生 ConnectionFactory ,您可以通过 spring.jms.* 中的外部配置属性来控制这些设置:

    spring.jms.cache.session-cache-size=5
    

    如果您想使用原生池,则可以通过向其添加依赖项 org.messaginghub:pooled-jms 并对 JmsPoolConnectionFactory 进行相应的配置来实现,如以下示例所示:

    spring.artemis.pool.enabled=true
    spring.artemis.pool.max-connections=50
    

    请参阅 ArtemisProperties 以获取更多受支持的选项。

    不涉及 JNDI 查找,并且使用 Artemis 配置中的 name 属性或通过配置提供的名称来根据目的地名称解析目的地。

    1.3. 使用 JNDI ConnectionFactory

    如果您正在应用程序服务器中运行应用程序,则 Spring Boot 会尝试使用 JNDI 查找 JMS ConnectionFactory 。默认情况下,会检查 java:/JmsXAjava:/XAConnectionFactory 位置。如果需要指定替代位置,则可以使用 spring.jms.jndi-name 属性,如以下示例所示:

    spring.jms.jndi-name=java:/MyConnectionFactory
    

    1.4. 发送消息

    Spring JmsTemplate 是自动配置的,您可以将其直接注入到您自己的 bean 中,如以下示例所示:

    import org.springframework.jms.core.JmsTemplate;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBean {
    
        private final JmsTemplate jmsTemplate;
    
        public MyBean(JmsTemplate jmsTemplate) {
            this.jmsTemplate = jmsTemplate;
        }
    
        public void someMethod() {
            this.jmsTemplate.convertAndSend("hello");
        }
    
    }
    

    可以以类似方式注入 JmsMessagingTemplate 。如果定义了 DestinationResolverMessageConverter bean ,则将其自动关联到自动配置的 JmsTemplate

    1.5. 接收消息

    存在 JMS 基础设施时,可以对任何 bean 进行 @JmsListener 注解以创建监听器端点。如果未定义JmsListenerContainerFactory,则会自动配置一个默认值。如果定义了 DestinationResolverMessageConverter bean ,它将自动关联到默认工厂。

    默认情况下,默认工厂是事务性的。如果您在存在 JtaTransactionManager 的基础设施中运行,则默认情况下它将与监听器容器关联。如果不是,则启用 sessionTransacted 标志。在后一种情况下,您可以通过添加 @Transactional 到监听器方法(或其委托)将本地数据存储事务与传入消息的处理相关联。这样可以确保本地事务完成后,传入消息得到确认。这还包括发送在同一个 JMS 会话上执行的响应消息。

    以下组件在 someQueue 目的地上创建一个监听器端点:

    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBean {
    
        @JmsListener(destination = "someQueue")
        public void processMessage(String content) {
            // ...
        }
    
    }
    

    有关更多详细信息,请参见的 @EnableJms

    如果您需要创建更多 JmsListenerContainerFactory 实例,或者想要覆盖默认实例,Spring Boot提供了一个 DefaultJmsListenerContainerFactoryConfigurer ,您可以使用与自动配置相同的设置来初始化 DefaultJmsListenerContainerFactory

    例如,以下示例公开了另一个使用特定 MessageConverter 的工厂:

    import javax.jms.ConnectionFactory;
    
    import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
    
    @Configuration(proxyBeanMethods = false)
    public class MyJmsConfiguration {
    
        @Bean
        public DefaultJmsListenerContainerFactory myFactory(DefaultJmsListenerContainerFactoryConfigurer configurer) {
            DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
            ConnectionFactory connectionFactory = getCustomConnectionFactory();
            configurer.configure(factory, connectionFactory);
            factory.setMessageConverter(new MyMessageConverter());
            return factory;
        }
    
        private ConnectionFactory getCustomConnectionFactory() {
            return ...
        }
    
    }
    

    然后,您可以在 @JmsListener 注解方法中使用工厂:

    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBean {
    
        @JmsListener(destination = "someQueue", containerFactory = "myFactory")
        public void processMessage(String content) {
            // ...
        }
    
    }
    

    2. AMQP

    高级消息队列协议(AMQP)是面向消息中间件的与平台无关的 wire-level 协议。Spring AMQP 项目将 Spring 的核心概念应用于基于 AMQP 的消息传递解决方案的开发。Spring Boot 为通过 RabbitMQ 使用 AMQP 提供了许多便利,包括 spring-boot-starter-amqp 启动器。

    2.1. RabbitMQ 支持

    RabbitMQ 是基于 AMQP 协议的轻量级,可靠,可扩展和可移植的消息代理。Spring 使用 RabbitMQ 通过 AMQP 协议进行通信。

    RabbitMQ 配置由 spring.rabbitmq.* 中的外部配置属性控制。例如,您可以在 application.properties 中声明以下部分:

    spring.rabbitmq.host=localhost
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=admin
    spring.rabbitmq.password=secret
    

    或者,您可以使用以下 addresses 属性配置相同的连接:

    spring.rabbitmq.addresses=amqp://admin:secret@localhost
    

    以这种方式指定地址时,hostport 属性将被忽略。如果地址使用 amqps 协议,则会自动启用 SSL 支持。

    有关更多受支持的基于属性的配置选项,请参阅 RabbitProperties 。要配置 Spring AMQP 使用的 RabbitMQ ConnectionFactory 的较低级别的详细信息,请定义一个 ConnectionFactoryCustomizer bean

    如果上下文中存在 ConnectionNameStrategy bean,它将自动用于命名由自动配置的 ConnectionFactory 创建的连接。

    有关更多详细信息,请参阅 了解 RabbitMQ 使用的协议 AMQP

    2.2. 发送信息

    Spring AmqpTemplateAmqpAdmin 是自动配置的,您可以将它们直接注入到自己的 bean 中,如以下示例所示:

    import org.springframework.amqp.core.AmqpAdmin;
    import org.springframework.amqp.core.AmqpTemplate;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBean {
    
        private final AmqpAdmin amqpAdmin;
    
        private final AmqpTemplate amqpTemplate;
    
        public MyBean(AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) {
            this.amqpAdmin = amqpAdmin;
            this.amqpTemplate = amqpTemplate;
        }
    
        public void someMethod() {
            this.amqpAdmin.getQueueInfo("someQueue");
        }
    
        public void someOtherMethod() {
            this.amqpTemplate.convertAndSend("hello");
        }
    
    }
    

    可以以类似方式注入 RabbitMessagingTemplate 。如果定义了 MessageConverter bean,它将自动关联到自动配置的 AmqpTemplate

    如有必要,任何定义为 org.springframework.amqp.core.Queue bean 的对象都会自动用于在 RabbitMQ 实例上声明相应的队列。

    要重试操作,可以在 AmqpTemplate上启用重试(例如,在代理连接丢失的情况下):

    spring.rabbitmq.template.retry.enabled=true
    spring.rabbitmq.template.retry.initial-interval=2s
    

    默认情况下,重试是禁用的。您也可以通过声明 RabbitRetryTemplateCustomizer bean 来以编程方式自定义RetryTemplate

    如果你需要创建更多 RabbitTemplate 实例或者你想覆盖默认值,Spring Boot 提供了一个 RabbitTemplateConfigurer bean,你可以使用它来初始化一个与自动配置使用的工厂相同设置的 RabbitTemplate

    2.3. 接收消息

    存在 Rabbit 基础设施时,可以对任何 bean 进行 @RabbitListener 注解以创建监听器端点。如果未定义 RabbitListenerContainerFactory ,则将自动配置 SimpleRabbitListenerContainerFactory ,并且您可以使用 spring.rabbitmq.listener.type 属性切换到直接容器。如果定义了 MessageConverterMessageRecoverer bean,将自动与默认工厂关联。

    以下示例组件在 someQueue 队列上创建一个监听器端点:

    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBean {
    
        @RabbitListener(queues = "someQueue")
        public void processMessage(String content) {
            // ...
        }
    
    }
    

    有关更多详细信息,请参见的 @EnableRabbit

    如果您需要创建更多 RabbitListenerContainerFactory 实例,或者想要覆盖默认实例,Spring Boot 提供了 SimpleRabbitListenerContainerFactoryConfigurerDirectRabbitListenerContainerFactoryConfigurer ,您可以用来初始化一个与自动配置所使用的工厂具有相同的设置的 SimpleRabbitListenerContainerFactoryDirectRabbitListenerContainerFactory

    选择哪种容器都没有关系。这两个 bean 通过自动配置公开。

    例如,以下配置类公开了另一个使用特定 MessageConverter 的工厂:

    import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
    import org.springframework.amqp.rabbit.connection.ConnectionFactory;
    import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration(proxyBeanMethods = false)
    public class MyRabbitConfiguration {
    
        @Bean
        public SimpleRabbitListenerContainerFactory myFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer) {
            SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
            ConnectionFactory connectionFactory = getCustomConnectionFactory();
            configurer.configure(factory, connectionFactory);
            factory.setMessageConverter(new MyMessageConverter());
            return factory;
        }
    
        private ConnectionFactory getCustomConnectionFactory() {
            return ...
        }
    
    }
    

    然后,您可以在任何带 @RabbitListener 注解的方法里使用工厂,如下所示:

    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBean {
    
        @RabbitListener(queues = "someQueue", containerFactory = "myFactory")
        public void processMessage(String content) {
            // ...
        }
    
    }
    

    您可以启用重试来处理监听器引发异常的情况。默认情况下,使用 RejectAndDontRequeueRecoverer ,但是您可以定义自己的 MessageRecoverer 。重试用尽后,则消息将被拒绝并被丢弃或路由到死信交换。默认情况下,重试是禁用的。您也可以通过声明 RabbitRetryTemplateCustomizer bean 来以编程方式自定义 RetryTemplate

    默认情况下,如果禁用了重试,并且监听器抛出异常,则会无限期地重试传递。您可以通过两种方式修改此行为:将 defaultRequeueRejected 属性设置为 false ,以便尝试进行零次重新传递,或者抛出 AmqpRejectAndDontRequeueException 来指示应该拒绝该消息。后者是启用重试并达到最大传递尝试次数时使用的机制。

    3. Apache Kafka 支持

    通过提供 spring-kafka 项目的自动配置来支持 Apache Kafka

    Kafka 配置由 spring.kafka.* 中的外部配置属性控制。例如,您可以在 application.properties 中声明以下部分:

    spring.kafka.bootstrap-servers=localhost:9092
    spring.kafka.consumer.group-id=myGroup
    

    要在启动时创建主题,请添加类型为 NewTopic 的 bean 。如果该主题已经存在,则将忽略该 bean 。

    请参阅 KafkaProperties 以获取更多受支持的选项。

    3.1. 发送信息

    Spring KafkaTemplate 是自动配置的,您可以直接在自己的 bean 中注入,如以下示例所示:

    import org.springframework.kafka.core.KafkaTemplate;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBean {
    
        private final KafkaTemplate<String, String> kafkaTemplate;
    
        public MyBean(KafkaTemplate<String, String> kafkaTemplate) {
            this.kafkaTemplate = kafkaTemplate;
        }
    
        public void someMethod() {
            this.kafkaTemplate.send("someTopic", "Hello");
        }
    
    }
    

    如果定义了 spring.kafka.producer.transaction-id-prefix 属性,则会自动配置 KafkaTransactionManager 。另外,如果定义了 RecordMessageConverter bean,它将自动关联到自动配置的 KafkaTemplate

    3.2. 接收消息

    存在 Apache Kafka 基础设施时,可以对任何 bean 进行 @KafkaListener 注解以创建监听器端点。如果尚未定义 KafkaListenerContainerFactory ,则会使用 spring.kafka.listener.* 中定义的键自动配置一个默认的。

    以下组件在 someTopic 主题上创建一个监听器端点:

    import org.springframework.kafka.annotation.KafkaListener;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBean {
    
        @KafkaListener(topics = "someTopic")
        public void processMessage(String content) {
            // ...
        }
    
    }
    

    如果定义了 KafkaTransactionManager bean ,它将自动关联到容器工厂。类似地,如果一个 RecordFilterStrategyCommonErrorHandler , AfterRollbackProcessorConsumerAwareRebalanceListener bean 被定义,它被自动关联到默认工厂。

    根据监听器的类型,RecordMessageConverterBatchMessageConverter bean 与默认工厂关联。如果对于批处理监听器仅存在一个 RecordMessageConverter bean,则将其包装在 BatchMessageConverter 中。

    自定义 ChainedKafkaTransactionManager 必须标记 @Primary ,因为它通常引用自动配置的 KafkaTransactionManager bean

    3.3. Kafka Streams

    Spring for Apache Kafka 提供了一个工厂 bean 来创建 StreamsBuilder 对象并管理流的生命周期。只要 kafka-streams 在类路径上并通过 @EnableKafkaStreams 注解启用 Kafka Streams,Spring Boot就会自动配置所需的KafkaStreamsConfiguration bean 。

    启用 Kafka Streams 意味着必须设置应用程序 ID 和引导服务器。可以使用 spring.kafka.streams.application-id 来配置前者,如果未设置,则默认为 spring.application.name 。后者可以全局设置,也可以仅针对流进行覆盖。

    通过专用属性可以设置额外属性。可以使用 spring.kafka.streams.properties 名称空间设置其他任意 Kafka 属性。另请参阅 额外Kafka 属性 以获取更多信息。

    要使用工厂 bean ,只需将 StreamsBuilder 连接到您的 @Bean ,如以下示例所示:

    import org.apache.kafka.common.serialization.Serdes;
    import org.apache.kafka.streams.KeyValue;
    import org.apache.kafka.streams.StreamsBuilder;
    import org.apache.kafka.streams.kstream.KStream;
    import org.apache.kafka.streams.kstream.Produced;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.kafka.annotation.EnableKafkaStreams;
    import org.springframework.kafka.support.serializer.JsonSerde;
    
    @Configuration(proxyBeanMethods = false)
    @EnableKafkaStreams
    public class MyKafkaStreamsConfiguration {
    
        @Bean
        public KStream<Integer, String> kStream(StreamsBuilder streamsBuilder) {
            KStream<Integer, String> stream = streamsBuilder.stream("ks1In");
            stream.map(this::uppercaseValue).to("ks1Out", Produced.with(Serdes.Integer(), new JsonSerde<>()));
            return stream;
        }
    
        private KeyValue<Integer, String> uppercaseValue(Integer key, String value) {
            return new KeyValue<>(key, value.toUpperCase());
        }
    
    }
    

    默认情况下,由 StreamBuilder 创建的对象管理的流将自动启动。您可以使用 spring.kafka.streams.auto-startup 属性来自定义此行为。

    3.4. Kafka 的额外属性

    自动配置支持的属性显示在附录的 集成属性 部分。请注意,在大多数情况下,这些属性(连字符或驼峰式)直接映射到 Apache Kafka 点属性。有关详细信息,请参阅 Apache Kafka 文档。

    这些属性的前几个属性适用于所有组件(生产者,使用者,管理员和流),但如果您希望使用不同的值,则可以在组件级别上指定。Apache Kafka 指定属性重要性为 HIGHMEDIUMLOW 。Spring Boot 自动配置支持所有 HIGH 重要性属性,一些选定的 MEDIUMLOW 属性以及任何没有默认值的属性。

    KafkaProperties 类直接提供了 Kafka 支持的属性的子集。如果希望使用不直接支持的其他属性来配置生产者或使用者,请使用以下属性:

    spring.kafka.properties[prop.one]=first
    spring.kafka.admin.properties[prop.two]=second
    spring.kafka.consumer.properties[prop.three]=third
    spring.kafka.producer.properties[prop.four]=fourth
    spring.kafka.streams.properties[prop.five]=fifth
    

    这会将通用的 Kafka 属性 prop.one 设置为 first(适用于生产者,消费者和管理员),将 admin 属性 prop.two 设置为 second ,将消费者属性 prop.three 设置为 third ,将生产者属性 prop.four 设置为 fourth ,并将流属性 prop.five 设置为 fifth

    您还可以按如下方式配置 Spring Kafka JsonDeserializer

    spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
    spring.kafka.consumer.properties[spring.json.value.default.type]=com.example.Invoice
    spring.kafka.consumer.properties[spring.json.trusted.packages]=com.example.main,com.example.another
    

    同样,您可以禁用 JsonSerializer 在标头中发送类型信息的默认行为:

    spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
    spring.kafka.producer.properties[spring.json.add.type.headers]=false
    

    以这种方式设置的属性将覆盖 Spring Boot 显式支持的任何配置项。

    3.5. 使用嵌入式 Kafka 进行测试

    Spring for Apache Kafka 提供了一种使用嵌入式 Apache Kafka 代理测试项目的便捷方法。要使用此功能,请在测试类上使用在 spring-kafka-test 模块中的 @EmbeddedKafka 注解。有关更多信息,请参阅 Spring for Apache Kafka 参考手册

    要使 Spring Boot 自动配置与上述嵌入式 Apache Kafka broker 一起使用,您需要将嵌入式 broker 地址(由 EmbeddedKafkaBroker 填充)的系统属性重新映射到 Apache Kafka 的 Spring Boot 配置属性中。有几种方法可以做到这一点:

    • 在测试类中,提供系统属性以将嵌入式代理地址映射到 spring.kafka.bootstrap-servers

      static {
          System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY, "spring.kafka.bootstrap-servers");
      }
      
    • @EmbeddedKafka 注解上配置属性名称:

      import org.springframework.boot.test.context.SpringBootTest;
      import org.springframework.kafka.test.context.EmbeddedKafka;
      
      @SpringBootTest
      @EmbeddedKafka(topics = "someTopic", bootstrapServersProperty = "spring.kafka.bootstrap-servers")
      class MyTest {
      
          // ...
      
      }
      
    • 在配置属性中使用占位符:

      spring.kafka.bootstrap-servers=${spring.embedded.kafka.brokers}
      

    4. RSocket

    RSocket 是用于字节流传输的二进制协议。它通过在单个连接上传递异步消息来实现对称交互模型。

    Spring Framework 的 spring-messaging 模块在客户端和服务器端的 RSocket 请求者和响应者提供支持。有关更多详细信息,请参阅 Spring Framework 参考的 RSocket 部分 ,包括 RSocket 协议的概述。

    4.1. RSocket 策略自动配置

    Spring Boot 自动配置一个 RSocketStrategies bean,该 bean 提供了用于编码和解码 RSocket 有效负载的所有必需基础设施。默认情况下,自动配置将尝试(按顺序)配置以下内容:

    1. Jackson 的 CBOR 编解码器
    2. Jackson 的 JSON 编解码器

    spring-boot-starter-rsocket 启动器提供了这两个依赖项。请参阅 Jackson 支持部分

    开发人员可以通过创建实现 RSocketStrategiesCustomizer 接口的 bean 来自定义 RSocketStrategies 组件。请注意,@Order 很重要,因为它决定了编解码器的顺序。

    4.2. RSocket 服务器自动配置

    Spring Boot 提供了 RSocket 服务器自动配置。所需的依赖项由 spring-boot-starter-rsocket 提供。

    Spring Boot 允许从 WebFlux 服务器通过 WebSocket 公开 RSocket ,或支持独立的 RSocket 服务器。这取决于应用程序的类型及其配置。

    对于 WebFlux 应用(即 WebApplicationType.REACTIVE 类型),仅当以下属性匹配时,RSocket 服务器才会插入 Web 服务器:

    spring.rsocket.server.mapping-path=/rsocket
    spring.rsocket.server.transport=websocket
    

    仅 Reactor Netty 支持将 RSocket 插入 Web 服务器,因为 RSocket 本身是使用该库构建的。

    或者,RSocket TCP 或 websocket 服务器也可以作为独立的嵌入式服务器启动。除了依赖项要求之外,唯一需要的配置是为该服务器定义端口:

    spring.rsocket.server.port=9898
    

    4.3. Spring Messaging RSocket 支持

    Spring Boot 将为 RSocket 自动配置 Spring Messaging 基础设施。

    这意味着 Spring Boot 将创建一个 RSocketMessageHandler bean 来处理对应用程序的 RSocket 请求。

    4.4. 使用 RSocketRequester 调用 RSocket 服务

    一旦 RSocket 在服务器和客户端之间建立了通道,任何一方都可以向另一方发送或接收请求。

    作为服务器,您可以在 RSocket @Controller 的任何处理程序方法上注入 RSocketRequester 实例。作为客户端,您需要首先配置和建立 RSocket 连接。对于这种情况,Spring Boot 使用预期的编解码器自动配置 RSocketRequester.Builder ,并应用任何 RSocketConnectorConfigurer bean 。

    RSocketRequester.Builder 实例是一个原型 bean ,这意味着每个注入点将为您提供一个新实例。这是有意为之的,因为此构建器是有状态的,您不应使用同一实例创建具有不同设置的请求者。

    以下代码显示了一个典型示例:

    import reactor.core.publisher.Mono;
    
    import org.springframework.messaging.rsocket.RSocketRequester;
    import org.springframework.stereotype.Service;
    
    @Service
    public class MyService {
    
        private final RSocketRequester rsocketRequester;
    
        public MyService(RSocketRequester.Builder rsocketRequesterBuilder) {
            this.rsocketRequester = rsocketRequesterBuilder.tcp("example.org", 9898);
        }
    
        public Mono<User> someRSocketCall(String name) {
            return this.rsocketRequester.route("user").data(name).retrieveMono(User.class);
        }
    
    }
    

    5. Spring Integration

    Spring Boot 为使用 Spring Integration 提供了许多便利,包括 spring-boot-starter-integration 启动器。Spring Integration 为消息传递以及其他传输(例如 HTTP,TCP 等)提供抽象。如果您的类路径上有 Spring Integration ,则可以通过 @EnableIntegration 注释对其进行初始化。

    Spring Integration polling 逻辑依赖于 自动配置的 TaskScheduler 。可以使用 spring.integration.poller.* 配置属性自定义默认 PollerMetadata(每秒轮询无限数量的消息) 。

    Spring Boot 还配置了一些功能,这些功能由其他 Spring Integration 模块的存在触发。如果 spring-integration-jmx 也在类路径上,则通过 JMX 发布消息处理统计信息。如果 spring-integration-jdbc 可用,则可以在启动时创建默认的数据库模式,如以下行所示:

    spring.integration.jdbc.initialize-schema=always
    

    如果 spring-integration-rsocket 可用,开发人员可以使用 spring.rsocket.server.* 属性配置 RSocket 服务器,并让它使用 IntegrationRSocketEndpointRSocketOutboundGateway 组件来处理传入的 RSocket 消息。此基础设施可以处理 Spring Integration RSocket 通道适配器和 @MessageMapping 处理器( spring.integration.rsocket.server.message-mapping-enabled 已配置)。

    Spring Boot 还可以使用配置属性来自动配置 ClientRSocketConnector

    # Connecting to a RSocket server over TCP
    spring.integration.rsocket.client.host=example.org
    spring.integration.rsocket.client.port=9898
    
    # Connecting to a RSocket Server over WebSocket
    spring.integration.rsocket.client.uri=ws://example.org
    

    有关更多详细信息,请参阅 IntegrationAutoConfigurationIntegrationProperties 类。

    6. WebSockets

    Spring Boot 为嵌入式 Tomcat 、Jetty 和 Undertow 提供 WebSockets 自动配置。如果将 war 文件部署到独立容器,Spring Boot 假定容器负责配置其 WebSocket 支持。

    Spring Framework 为 MVC Web 应用程序提供了 丰富的 WebSocket 支持,可以通过 spring-boot-starter-websocket 模块轻松获得。

    WebSocket 支持也可用于 响应式 Web 应用程序 ,并且需要同时包含 spring-boot-starter-webflux 和 WebSocket API :

    <dependency>
        <groupId>javax.websocket</groupId>
        <artifactId>javax.websocket-api</artifactId>
    </dependency>
    
  • 相关阅读:
    C语言I博客作业05 sun
    C语言I博客作业08 sun
    C语言I博客作业02 sun
    C语言I博客作业04 sun
    elastix的web端口修改
    mysql.proc错误解决
    Client.Error.MessageSend 错误解决方案
    让secureCRT正确显示中文
    elastix的多个inbound route的设置
    PHP5.1时间相差8小时问题解决。
  • 原文地址:https://www.cnblogs.com/huangwenjie/p/16354174.html
Copyright © 2020-2023  润新知