当前位置: 首页 > news >正文

Spring Boot 的自动配置,以rabbitmq为例,请详细说明

Spring Boot 的自动配置特性能够大大简化集成外部服务和组件的配置过程。以 RabbitMQ 为例,Spring Boot 通过 spring-boot-starter-amqp 提供了自动配置支持,开发者只需在应用中添加相关依赖并配置必要的属性,Spring Boot 会自动配置所需的连接工厂、消息队列、交换机、消息模板等。

以下是以 RabbitMQ 为例的详细说明。

1. 引入 RabbitMQ 依赖

要使用 Spring Boot 集成 RabbitMQ,首先需要在项目的 pom.xml 文件中添加 spring-boot-starter-amqp 依赖,这个依赖包含了与 RabbitMQ 交互的所有必要组件。

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

spring-boot-starter-amqp 依赖包含了 Spring AMQPRabbitMQ 的连接组件,自动配置会根据此依赖自动启用 RabbitMQ 相关功能。

2. 配置 RabbitMQ 连接属性

接下来,你需要在 application.propertiesapplication.yml 中配置 RabbitMQ 的连接信息。例如:

使用 application.properties
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
spring.rabbitmq.publisher-confirm-type=simple
spring.rabbitmq.listener.simple.concurrency=3
spring.rabbitmq.listener.simple.max-concurrency=10
  • spring.rabbitmq.host:RabbitMQ 服务器的地址,通常是 localhost
  • spring.rabbitmq.port:RabbitMQ 服务器的端口,默认是 5672
  • spring.rabbitmq.username 和 spring.rabbitmq.password:RabbitMQ 的认证信息。
  • spring.rabbitmq.virtual-host:虚拟主机,通常是 /
  • spring.rabbitmq.publisher-confirm-type:确认模式,simple 为简单确认。
  • spring.rabbitmq.listener.simple.concurrency:并发消费者数量。
  • spring.rabbitmq.listener.simple.max-concurrency:最大消费者数量。

 

Spring Boot 会读取这些配置并自动配置连接工厂、消息队列监听器等。

3. 自动配置的原理

Spring Boot 在启动时会通过 spring-boot-autoconfigure 模块自动配置 RabbitMQ 相关的 Bean,主要通过以下几个步骤:

3.1 自动配置连接工厂(ConnectionFactory

Spring Boot 会根据 spring.rabbitmq.* 配置自动创建一个 ConnectionFactory,它负责与 RabbitMQ 服务器建立连接。通常,Spring Boot 默认使用 CachingConnectionFactory 来实现连接工厂。

@Bean
@Primary
@ConditionalOnMissingBean(ConnectionFactory.class)
public CachingConnectionFactory connectionFactory() {CachingConnectionFactory connectionFactory = new CachingConnectionFactory();connectionFactory.setHost(rabbitProperties.getHost());connectionFactory.setPort(rabbitProperties.getPort());connectionFactory.setUsername(rabbitProperties.getUsername());connectionFactory.setPassword(rabbitProperties.getPassword());connectionFactory.setVirtualHost(rabbitProperties.getVirtualHost());return connectionFactory;
}
  • @ConditionalOnMissingBean 表示如果应用上下文中没有 ConnectionFactory 的 Bean,Spring Boot 会创建一个默认的 CachingConnectionFactory
  • 配置的 spring.rabbitmq.* 参数将被注入到这个 ConnectionFactory 中。
3.2 自动配置 RabbitTemplate

RabbitTemplate 是 Spring AMQP 用来发送消息的核心类。Spring Boot 会自动配置一个 RabbitTemplate,它使用 ConnectionFactory 来与 RabbitMQ 服务器进行交互。

@Bean
@ConditionalOnMissingBean(RabbitTemplate.class)
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate template = new RabbitTemplate(connectionFactory);template.setMessageConverter(new Jackson2JsonMessageConverter());return template;
}
  • RabbitTemplate 被用来发送消息,Spring Boot 自动创建并配置。
  • 默认使用 JSON 消息转换器(Jackson2JsonMessageConverter)将消息转换为 JSON 格式。
3.3 自动配置 RabbitListenerContainerFactory

如果你想使用 @RabbitListener 注解来监听 RabbitMQ 消息队列,Spring Boot 会自动配置 RabbitListenerContainerFactory

@Bean
@ConditionalOnMissingBean(RabbitListenerContainerFactory.class)
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, RabbitProperties rabbitProperties) {SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();factory.setConnectionFactory(connectionFactory);factory.setConcurrency(rabbitProperties.getListener().getSimple().getConcurrency());factory.setMaxConcurrency(rabbitProperties.getListener().getSimple().getMaxConcurrency());return factory;
}
  • 这个工厂用于创建 RabbitMQ 消息监听容器,容器负责消费队列中的消息。
  • setConcurrency 和 setMaxConcurrency 用来配置消息消费者的并发数。
3.4 自动配置消息监听器(@RabbitListener

Spring Boot 会自动启用对 @RabbitListener 注解的支持。你可以使用 @RabbitListener 注解创建消息监听器,而无需手动配置监听容器。

4. 创建消费者和生产者

4.1 消息生产者(发送消息)

你可以使用 RabbitTemplate 发送消息到 RabbitMQ 队列。

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MessageProducer {@Autowiredprivate RabbitTemplate rabbitTemplate;public void sendMessage(String message) {rabbitTemplate.convertAndSend("myQueue", message);}
}
  • rabbitTemplate.convertAndSend 方法用于将消息发送到指定的队列(myQueue)。
  • Spring Boot 会自动为你配置队列、交换机、路由等。
4.2 消息消费者(监听消息)

你可以使用 @RabbitListener 注解来创建消息消费者,监听指定的队列,并在消息到达时处理它。

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;@Service
public class MessageConsumer {@RabbitListener(queues = "myQueue")public void receiveMessage(String message) {System.out.println("Received message: " + message);}
}
  • @RabbitListener 注解会告诉 Spring Boot 自动创建一个消息监听器并连接到指定的队列。
  • 每当有消息进入 myQueue 队列时,receiveMessage 方法就会被调用。

5. 自定义配置

你可以进一步自定义 RabbitMQ 的配置,以下是一些常见的自定义场景:

5.1 配置交换机、队列和绑定

你可以定义自己的交换机、队列和绑定,确保它们符合你的应用需求。例如:

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RabbitConfig {@Beanpublic Queue myQueue() {return new Queue("myQueue", true);}@Beanpublic TopicExchange exchange() {return new TopicExchange("myExchange");}@Beanpublic Binding binding(Queue myQueue, TopicExchange exchange) {return BindingBuilder.bind(myQueue).to(exchange).with("myQueue.#");}
}
  • Queue 定义了一个消息队列。
  • TopicExchange 定义了一个交换机。
  • Binding 定义了队列和交换机之间的绑定关系。
5.2 配置消息监听器的并发

你可以通过 application.propertiesapplication.yml 来调整消息监听器的并发配置:

spring.rabbitmq.listener.simple.concurrency=5
spring.rabbitmq.listener.simple.max-concurrency=10

这将允许 Spring Boot 动态调整消费者线程的数量,确保队列消息能够高效消费。

总结

Spring Boot 通过自动配置 RabbitMQ 连接、消息发送和消费等相关组件,极大地简化了 RabbitMQ 的集成过程。只需添加 spring-boot-starter-amqp 依赖并在配置文件中指定必要的参数,Spring Boot 就会自动配置所需的所有组件,并根据需求自动启动消息生产者和消费者。你可以通过注解 @RabbitListener 来定义消息监听器,也可以自定义交换机、队列和绑定等配置,从而满足不同的业务需求。

通过源码再次,详细说明

要深入了解 Spring Boot 如何通过自动配置集成 RabbitMQ,我们需要通过源码分析它是如何工作的。Spring Boot 使用了 spring-boot-starter-amqp 来简化 RabbitMQ 的配置。以下是从源代码角度对 Spring Boot 如何自动配置 RabbitMQ 进行详细说明的过程。

1. Spring Boot 启动流程和自动配置

Spring Boot 使用了 @EnableAutoConfiguration 注解和 spring.factories 文件来实现自动配置。在启动时,Spring Boot 会扫描并自动配置与应用上下文相关的配置类。RabbitMQ 的自动配置就是通过这些配置类实现的。

1.1 spring-boot-starter-amqp 依赖

首先,spring-boot-starter-amqp 依赖包含了 Spring AMQP 和 RabbitMQ 的集成依赖,并提供了 RabbitMQ 自动配置的支持。它的 spring.factories 文件列出了与 RabbitMQ 相关的自动配置类。

spring-boot-starter-amqp 中,spring.factories 文件会自动引入 RabbitAutoConfiguration 类。你可以在 spring-boot-starter-amqp 依赖中看到这一点:

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

当你引入了这个依赖后,Spring Boot 会自动加载 RabbitMQ 的相关配置。

2. RabbitAutoConfiguration 类

Spring Boot 的 RabbitMQ 自动配置类是 RabbitAutoConfiguration,它位于 org.springframework.boot.autoconfigure.amqp 包中。这个类的作用是基于你的配置自动设置 RabbitMQ 连接、队列、交换机等。

我们来分析一下 RabbitAutoConfiguration 类的源码:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(CachingConnectionFactory.class)
@ConditionalOnProperty(prefix = "spring.rabbitmq", name = "host")
@EnableConfigurationProperties(RabbitProperties.class)
@Import({ RabbitListenerConfiguration.class, RabbitManagementConfigurer.class })
public class RabbitAutoConfiguration {private static final Logger logger = LoggerFactory.getLogger(RabbitAutoConfiguration.class);private final RabbitProperties properties;public RabbitAutoConfiguration(RabbitProperties properties) {this.properties = properties;}@Bean@ConditionalOnMissingBean(ConnectionFactory.class)public CachingConnectionFactory connectionFactory() {logger.debug("Creating CachingConnectionFactory");CachingConnectionFactory factory = new CachingConnectionFactory();factory.setHost(this.properties.getHost());factory.setPort(this.properties.getPort());factory.setUsername(this.properties.getUsername());factory.setPassword(this.properties.getPassword());factory.setVirtualHost(this.properties.getVirtualHost());return factory;}@Bean@ConditionalOnMissingBean(RabbitTemplate.class)public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());return rabbitTemplate;}@Bean@ConditionalOnMissingBean(SimpleRabbitListenerContainerFactory.class)public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, RabbitProperties rabbitProperties) {SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();factory.setConnectionFactory(connectionFactory);factory.setConcurrency(rabbitProperties.getListener().getSimple().getConcurrency());factory.setMaxConcurrency(rabbitProperties.getListener().getSimple().getMaxConcurrency());return factory;}
}

2.1 @Configuration 和 @EnableConfigurationProperties

  • @Configuration(proxyBeanMethods = false):这是一个配置类,proxyBeanMethods = false 表示这个配置类不会使用代理,也就是说,它只会影响当前类中定义的 bean。
  • @EnableConfigurationProperties(RabbitProperties.class):该注解使得 RabbitProperties 类成为一个配置属性类,允许 Spring Boot 自动加载配置文件中的 spring.rabbitmq.* 属性,并将它们绑定到 RabbitProperties 对象。

2.2 connectionFactory Bean

@Bean
@ConditionalOnMissingBean(ConnectionFactory.class)
public CachingConnectionFactory connectionFactory() {CachingConnectionFactory factory = new CachingConnectionFactory();factory.setHost(this.properties.getHost());factory.setPort(this.properties.getPort());factory.setUsername(this.properties.getUsername());factory.setPassword(this.properties.getPassword());factory.setVirtualHost(this.properties.getVirtualHost());return factory;
}
  • @ConditionalOnMissingBean(ConnectionFactory.class):这表示如果应用上下文中没有 ConnectionFactory 类型的 Bean,Spring Boot 会自动创建一个 CachingConnectionFactory 的实例。CachingConnectionFactory 是 Spring AMQP 提供的一个连接工厂实现,它能缓存到 RabbitMQ 的连接以提高性能。
  • factory.setHost 等:这些配置项通过 RabbitProperties 类从 application.properties 或 application.yml 中读取并注入。

2.3 rabbitTemplate Bean

@Bean
@ConditionalOnMissingBean(RabbitTemplate.class)
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());return rabbitTemplate;
}
  • @ConditionalOnMissingBean(RabbitTemplate.class):如果 RabbitTemplate 已经存在于应用上下文中,Spring Boot 就不会再次创建它。
  • RabbitTemplate:它是与 RabbitMQ 交互的核心类,主要用于发送消息。Spring Boot 会自动创建并配置 RabbitTemplate,并将其与上面创建的 ConnectionFactory 关联。

2.4 rabbitListenerContainerFactory Bean

@Bean
@ConditionalOnMissingBean(SimpleRabbitListenerContainerFactory.class)
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, RabbitProperties rabbitProperties) {SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();factory.setConnectionFactory(connectionFactory);factory.setConcurrency(rabbitProperties.getListener().getSimple().getConcurrency());factory.setMaxConcurrency(rabbitProperties.getListener().getSimple().getMaxConcurrency());return factory;
}
  • SimpleRabbitListenerContainerFactory:这是一个用来创建 RabbitMQ 消息监听容器的工厂。该容器负责从 RabbitMQ 中接收并处理消息。
  • setConcurrency 和 setMaxConcurrency:这两个方法控制监听器的并发性,指定了消息监听的最小和最大并发数。

3. RabbitListenerConfiguration 和 RabbitManagementConfigurer

RabbitAutoConfiguration 类还通过 @Import 注解引入了 RabbitListenerConfigurationRabbitManagementConfigurer 类。这些类负责配置消息监听器和管理接口等。

 

java

@Import({ RabbitListenerConfiguration.class, RabbitManagementConfigurer.class })

  • RabbitListenerConfiguration:负责配置和启用 @RabbitListener 注解的处理。
  • RabbitManagementConfigurer:负责 RabbitMQ 管理的配置,通常是为了启用或配置 RabbitMQ 管理界面。

4. RabbitProperties 类

RabbitProperties 类是用来封装 application.propertiesapplication.yml 中与 RabbitMQ 相关的配置项的。它的主要作用是将这些配置绑定到 Java 对象上,方便后续使用。

@ConfigurationProperties(prefix = "spring.rabbitmq")
public class RabbitProperties {private String host = "localhost";private int port = 5672;private String username = "guest";private String password = "guest";private String virtualHost = "/";private Listener listener = new Listener();public static class Listener {private Simple simple = new Simple();public static class Simple {private int concurrency = 1;private int maxConcurrency = 1;}}// getters and setters
}

RabbitProperties 是一个 POJO 类,Spring Boot 会将 application.properties 中以 spring.rabbitmq.* 开头的属性自动映射到这个类的字段中。

5. @RabbitListener 注解支持

Spring Boot 自动配置还会启用 @RabbitListener 注解的支持,这意味着你可以通过注解驱动的方式来创建 RabbitMQ 消息监听器。例如:

@Service
public class MyListener {@RabbitListener(queues = "myQueue")public void handleMessage(String message) {System.out.println("Received message: " + message);}
}

6. 总结

通过 RabbitAutoConfiguration,Spring Boot 自动配置了与 RabbitMQ 交互所需的主要组件:ConnectionFactoryRabbitTemplateSimpleRabbitListenerContainerFactory 等。这些组件的创建是基于 application.properties 中的配置完成的。通过 Spring Boot 的自动配置,开发者只需要添加必要的依赖和配置,不必手动创建和配置这些复杂的 RabbitMQ 组件。

自动配置总结

  • ConnectionFactory:用于连接到 RabbitMQ 服务。
  • RabbitTemplate:用于发送消息。
  • SimpleRabbitListenerContainerFactory:用于配置消息监听容器。
  • RabbitListener 注解:用于处理消息监听。

RabbitAutoConfiguration 源码 1.5.9版本

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.boot.autoconfigure.amqp;import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties.Retry;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties.Ssl;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties.Template;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;@Configuration
@ConditionalOnClass({RabbitTemplate.class, Channel.class})
@EnableConfigurationProperties({RabbitProperties.class})
@Import({RabbitAnnotationDrivenConfiguration.class})
public class RabbitAutoConfiguration {public RabbitAutoConfiguration() {}@Configuration@ConditionalOnClass({RabbitMessagingTemplate.class})@ConditionalOnMissingBean({RabbitMessagingTemplate.class})@Import({RabbitAutoConfiguration.RabbitTemplateConfiguration.class})protected static class MessagingTemplateConfiguration {protected MessagingTemplateConfiguration() {}@Bean@ConditionalOnSingleCandidate(RabbitTemplate.class)public RabbitMessagingTemplate rabbitMessagingTemplate(RabbitTemplate rabbitTemplate) {return new RabbitMessagingTemplate(rabbitTemplate);}}@Configuration@Import({RabbitAutoConfiguration.RabbitConnectionFactoryCreator.class})protected static class RabbitTemplateConfiguration {private final ObjectProvider<MessageConverter> messageConverter;private final RabbitProperties properties;public RabbitTemplateConfiguration(ObjectProvider<MessageConverter> messageConverter, RabbitProperties properties) {this.messageConverter = messageConverter;this.properties = properties;}@Bean@ConditionalOnSingleCandidate(ConnectionFactory.class)@ConditionalOnMissingBean({RabbitTemplate.class})public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);MessageConverter messageConverter = (MessageConverter)this.messageConverter.getIfUnique();if (messageConverter != null) {rabbitTemplate.setMessageConverter(messageConverter);}rabbitTemplate.setMandatory(this.determineMandatoryFlag());Template templateProperties = this.properties.getTemplate();Retry retryProperties = templateProperties.getRetry();if (retryProperties.isEnabled()) {rabbitTemplate.setRetryTemplate(this.createRetryTemplate(retryProperties));}if (templateProperties.getReceiveTimeout() != null) {rabbitTemplate.setReceiveTimeout(templateProperties.getReceiveTimeout());}if (templateProperties.getReplyTimeout() != null) {rabbitTemplate.setReplyTimeout(templateProperties.getReplyTimeout());}return rabbitTemplate;}private boolean determineMandatoryFlag() {Boolean mandatory = this.properties.getTemplate().getMandatory();return mandatory != null ? mandatory : this.properties.isPublisherReturns();}private RetryTemplate createRetryTemplate(Retry properties) {RetryTemplate template = new RetryTemplate();SimpleRetryPolicy policy = new SimpleRetryPolicy();policy.setMaxAttempts(properties.getMaxAttempts());template.setRetryPolicy(policy);ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();backOffPolicy.setInitialInterval(properties.getInitialInterval());backOffPolicy.setMultiplier(properties.getMultiplier());backOffPolicy.setMaxInterval(properties.getMaxInterval());template.setBackOffPolicy(backOffPolicy);return template;}@Bean@ConditionalOnSingleCandidate(ConnectionFactory.class)@ConditionalOnProperty(prefix = "spring.rabbitmq",name = {"dynamic"},matchIfMissing = true)@ConditionalOnMissingBean({AmqpAdmin.class})public AmqpAdmin amqpAdmin(ConnectionFactory connectionFactory) {return new RabbitAdmin(connectionFactory);}}@Configuration@ConditionalOnMissingBean({ConnectionFactory.class})protected static class RabbitConnectionFactoryCreator {protected RabbitConnectionFactoryCreator() {}@Beanpublic CachingConnectionFactory rabbitConnectionFactory(RabbitProperties config) throws Exception {RabbitConnectionFactoryBean factory = new RabbitConnectionFactoryBean();if (config.determineHost() != null) {factory.setHost(config.determineHost());}factory.setPort(config.determinePort());if (config.determineUsername() != null) {factory.setUsername(config.determineUsername());}if (config.determinePassword() != null) {factory.setPassword(config.determinePassword());}if (config.determineVirtualHost() != null) {factory.setVirtualHost(config.determineVirtualHost());}if (config.getRequestedHeartbeat() != null) {factory.setRequestedHeartbeat(config.getRequestedHeartbeat());}Ssl ssl = config.getSsl();if (ssl.isEnabled()) {factory.setUseSSL(true);if (ssl.getAlgorithm() != null) {factory.setSslAlgorithm(ssl.getAlgorithm());}factory.setKeyStore(ssl.getKeyStore());factory.setKeyStorePassphrase(ssl.getKeyStorePassword());factory.setTrustStore(ssl.getTrustStore());factory.setTrustStorePassphrase(ssl.getTrustStorePassword());}if (config.getConnectionTimeout() != null) {factory.setConnectionTimeout(config.getConnectionTimeout());}factory.afterPropertiesSet();CachingConnectionFactory connectionFactory = new CachingConnectionFactory((com.rabbitmq.client.ConnectionFactory)factory.getObject());connectionFactory.setAddresses(config.determineAddresses());connectionFactory.setPublisherConfirms(config.isPublisherConfirms());connectionFactory.setPublisherReturns(config.isPublisherReturns());if (config.getCache().getChannel().getSize() != null) {connectionFactory.setChannelCacheSize(config.getCache().getChannel().getSize());}if (config.getCache().getConnection().getMode() != null) {connectionFactory.setCacheMode(config.getCache().getConnection().getMode());}if (config.getCache().getConnection().getSize() != null) {connectionFactory.setConnectionCacheSize(config.getCache().getConnection().getSize());}if (config.getCache().getChannel().getCheckoutTimeout() != null) {connectionFactory.setChannelCheckoutTimeout(config.getCache().getChannel().getCheckoutTimeout());}return connectionFactory;}}
}

 

相关文章:

Spring Boot 的自动配置,以rabbitmq为例,请详细说明

Spring Boot 的自动配置特性能够大大简化集成外部服务和组件的配置过程。以 RabbitMQ 为例&#xff0c;Spring Boot 通过 spring-boot-starter-amqp 提供了自动配置支持&#xff0c;开发者只需在应用中添加相关依赖并配置必要的属性&#xff0c;Spring Boot 会自动配置所需的连…...

Visual Studio 2022+Qt6.5.3安装教程+环境配置+创建Qt项目+乱码插件+运行很完美(16岁孩子也能看懂)

点击上方"蓝字"关注我们 01、安装VS2022 >>> 一、安装VS2022 1、VS2022下载链接:Visual Studio 2022 IDE - 适用于软件开发人员的编程工具[https://visualstudio.microsoft.com/zh-hans/vs/] 2、选择Community 2022个人免费版,点击下载[https://gitcode.…...

LeetCode - 初级算法 数组(旋转数组)

旋转数组 这篇文章讨论如何通过编程实现数组元素的旋转操作。 免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 描述 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例: 输入: nums = [1,2,3,...

logback日志框架源码分析

目录 (一)入口:slf4j选择日志框架 (二)日志框架初始化 (1)logback的3种配置方式 a、BasicConfigurator默认配置 b、SPI方式配置的Configurator实现类 c、通过配置文件初始化 (2)xml配置文件初始化 (三)Logger的创建 (四)打印日志 本文源码基于:logback版…...

【微服务】3、配置管理

微服务配置管理 已掌握的微服务组件及配置管理问题引出 已掌握注册中心、Openfan、远程调用、负载均衡、网关等组件&#xff0c;具备微服务开发能力&#xff0c;但仍存在其他问题待解决。微服务和网关存在大量配置文件&#xff0c;其中包含很多重复配置&#xff0c;如数据库、日…...

数据分析思维(七):分析方法——群组分析方法

数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python&#xff0c;更重要的是数据分析思维。没有数据分析思维和业务知识&#xff0c;就算拿到一堆数据&#xff0c;也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》&#xff0c;本文内容就是提取…...

概述(讲讲python基本语法和第三方库)

我是北子&#xff0c;这是我自己写的python教程&#xff0c;主要是记录自己的学习成果方便自己日后复习&#xff0c; 我先学了C/C&#xff0c;所以这套教程中可能会将很多概念和C/C去对比&#xff0c;所以该教程大概不适合零基础的人。 it seems that python nowadays 只在人工…...

力扣-20-有效的括号-栈

思路&#xff1a; 左括号每次匹配都是先匹配最后进来的&#xff0c;和栈的特点很相似&#xff0c;我们就可以利用栈来完成...

数据在内存中的存储【C语言版】

目录 1.举例&#xff1a; 2.深入刨析大端小端的组成&#xff1a; 3.判断当前编译环境是大端还是小端的方法 4.以函数的形式来判断当前的编译环境是大端还是小端【就是把判断大端小端的方法放进函数里面来实现&#xff0c;得到返回值&#xff0c;可以减少main()函数的内存】…...

【SQL】进阶知识 — 各大数据库合并几条数据到一行的方式

大家好&#xff0c;欢迎来到本期的 SQL 知识分享&#xff01;今天我们要聊一个非常实用的技能&#xff1a;如何将多个行数据合并成一行&#xff01;如果你曾经需要把多个查询结果合并成一个单元&#xff0c;或者把多行数据汇总到一个字段中&#xff0c;这篇文章将会教你如何用 …...

Gitee上传项目代码教程(详细)

工具必备&#xff1a;Git Bash 上传步骤 1.在Gitee创建项目仓库 2.进入本地项目目录 右键打开Git Bash here 3.配置用户名和邮箱 如果之前给git配置过用户名和邮箱可跳过 查看Git是否配置成功&#xff1a;git config --list git config --global user.name "xxx"…...

python ijson 用法教程

ijson PyPI Python ijson处理大型JSON文件 - 秀尊云 Python解析JSON大文件 | Leetaos Blog https://stackoverflow.com/questions/2400643/is-there-a-memory-efficient-and-fast-way-to-load-big-json-files/58148422#58148422 Python中读写&#xff08;解析&#xff09;J…...

什么是网络安全攻防演练,即红蓝对抗?

定义与目的 定义&#xff1a;网络安全攻防演练是一种模拟真实网络攻击和防御场景的活动&#xff0c;通过组织专业的攻击队伍&#xff08;红队&#xff09;和防御队伍&#xff08;蓝队&#xff09;进行对抗&#xff0c;来检验和提升组织的网络安全防御能力、应急响应能力和安全运…...

数据挖掘——决策树分类

数据挖掘——决策树分类 决策树分类Hunt算法信息增益增益比率基尼指数连续数据总结 决策树分类 树状结构&#xff0c;可以很好的对数据进行分类&#xff1b; 决策树的根节点到叶节点的每一条路径构建一条规则&#xff1b;具有互斥且完备的特点&#xff0c;即每一个样本均被且…...

Pytorch单、多GPU和CPU训练模型保存和加载

Pytorch多GPU训练模型保存和加载 在多GPU训练中&#xff0c;模型通常被包装在torch.nn.DataParallel或torch.nn.parallel.DistributedDataParallel中&#xff0c;这会在模型的参数名前加上module前缀。因此&#xff0c;在保存模型时&#xff0c;需要使用model.module.state_di…...

Karate 介绍与快速示例(API测试自动化、模拟、性能测试与UI自动化工具)

Karate是一个将API测试自动化、模拟、性能测试甚至UI自动化结合到一个统一框架中的开源工具。 Karate使用Gherkin 的BDD语法,是语言中性的,即使是非程序员也很容易。断言和HTML报告是内置的,支持并行运行测试以提高速度Karate 是用Java语言编写, 可以在Java 项目项目中运行…...

Pytest 高级用法:间接参数化

文章目录 1. 引言2. 基础概念2.1 Fixture2.2 参数化 3. 代码实例3.1 基础设置3.2 测试用例示例示例 1&#xff1a;基础的间接参数化示例 2&#xff1a;通过 request 获取参数值示例 3&#xff1a;多参数组合测试示例 4&#xff1a;部分间接参数化 4. 最佳实践5. 总结参考资料 1…...

第07章 存储管理(一)

一、磁盘简介 1.1 名称称呼 磁盘/硬盘/disk是同一个东西&#xff0c;不同于内存的是容量比较大。 1.2 类型 机械&#xff1a;机械硬盘即是传统普通硬盘&#xff0c;主要由&#xff1a;盘片&#xff0c;磁头&#xff0c;盘片转轴及控制电机&#xff0c;磁头控制器&#xff0…...

Go语言的 的设计模式(Design Patterns)核心知识

Go语言的设计模式&#xff08;Design Patterns&#xff09;核心知识 Go语言&#xff08;Golang&#xff09;是一种静态类型、编译型的编程语言&#xff0c;自2009年由Google正式推出以来&#xff0c;因其高效的性能、卓越的并发能力以及简洁的语法受到广泛欢迎。在软件开发中&…...

js函数预览图片:支持鼠标和手势拖拽缩放

对之前的方式改进&#xff1a;原生js实现图片预览控件&#xff0c;支持丝滑拖拽&#xff0c;滚轮放缩&#xff0c;放缩聚焦_js图片预览-CSDN博客 /*** 图片预览函数&#xff0c;调用后自动预览图片* param {图片地址} imgurl*/ function openImagePreview(imgurl) {if (!imgurl…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...