重学SpringBoot3-异步编程完全指南

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》
期待您的点赞👍收藏⭐评论✍

重学SpringBoot3-异步编程完全指南

  • 1. 简介
  • 2. @Async注解
    • 2.1 基础配置
    • 2.2 基本使用
    • 2.3 自定义线程池
  • 3. WebFlux响应式编程
    • 3.1 依赖配置
    • 3.2 响应式Controller示例
    • 3.3 响应式Service实现
  • 4. CompletableFuture的使用
    • 4.1 基本操作
    • 4.2 组合操作
  • 5. 事件驱动模型
    • 5.1 自定义事件
    • 5.2 事件监听器
  • 6. 消息队列(MQ)异步处理
    • 6.1 RabbitMQ配置
    • 6.2 消息队列配置类
    • 6.3 消息生产者
    • 6.4 消息消费者
    • 6.5 消息确认机制
  • 7. 最佳实践
    • 7.1 异常处理
    • 7.2 线程池配置
    • 7.3 性能优化
    • 7.4 消息队列使用建议
  • 8. 总结
  • 参考资料

1. 简介

在现代应用程序开发中,异步编程已经成为提升应用性能和用户体验的重要手段。SpringBoot 3提供了多种异步编程的方式,本文将详细介绍这些实现方式及其最佳实践。

2. @Async注解

2.1 基础配置

首先需要在启动类或配置类上启用异步支持:

@EnableAsync
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2.2 基本使用

@Service
public class EmailService {
    @Async
    public CompletableFuture<String> sendEmail(String to) {
        // 模拟发送邮件耗时
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return CompletableFuture.completedFuture("邮件发送成功:" + to);
    }
}

2.3 自定义线程池

@Configuration
public class AsyncConfig implements AsyncConfigurer {
    
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("AsyncThread-");
        executor.initialize();
        return executor;
    }
    
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}

3. WebFlux响应式编程

3.1 依赖配置

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

3.2 响应式Controller示例

@RestController
@RequestMapping("/api")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping("/users")
    public Flux<User> getAllUsers() {
        return userService.findAllUsers();
    }
    
    @GetMapping("/users/{id}")
    public Mono<User> getUser(@PathVariable String id) {
        return userService.findById(id);
    }
}

3.3 响应式Service实现

@Service
public class UserService {
    
    public Flux<User> findAllUsers() {
        return Flux.fromIterable(users)
                   .delayElements(Duration.ofMillis(100));
    }
    
    public Mono<User> findById(String id) {
        return Mono.justOrEmpty(findUserById(id))
                   .delayElement(Duration.ofMillis(100));
    }
}

4. CompletableFuture的使用

4.1 基本操作

@Service
public class OrderService {
    
    public CompletableFuture<Order> processOrder(Order order) {
        return CompletableFuture.supplyAsync(() -> {
            // 处理订单逻辑
            return order;
        });
    }
    
    public CompletableFuture<Order> validateOrder(Order order) {
        return CompletableFuture.supplyAsync(() -> {
            // 验证订单逻辑
            return order;
        });
    }
}

4.2 组合操作

public CompletableFuture<Order> createOrder(Order order) {
    return validateOrder(order)
            .thenCompose(this::processOrder)
            .thenApply(processedOrder -> {
                // 更新订单状态
                return processedOrder;
            })
            .exceptionally(ex -> {
                // 异常处理
                log.error("订单处理失败", ex);
                return null;
            });
}

5. 事件驱动模型

5.1 自定义事件

public class OrderCreatedEvent extends ApplicationEvent {
    private final Order order;
    
    public OrderCreatedEvent(Object source, Order order) {
        super(source);
        this.order = order;
    }
    
    public Order getOrder() {
        return order;
    }
}

5.2 事件监听器

@Component
public class OrderEventListener {
    
    @Async
    @EventListener
    public void handleOrderCreatedEvent(OrderCreatedEvent event) {
        Order order = event.getOrder();
        // 异步处理订单逻辑
    }
}

6. 消息队列(MQ)异步处理

6.1 RabbitMQ配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

6.2 消息队列配置类

@Configuration
public class RabbitMQConfig {
    
    @Bean
    public Queue orderQueue() {
        return new Queue("order.queue", true);
    }
    
    @Bean
    public DirectExchange orderExchange() {
        return new DirectExchange("order.exchange");
    }
    
    @Bean
    public Binding orderBinding(Queue orderQueue, DirectExchange orderExchange) {
        return BindingBuilder.bind(orderQueue)
                .to(orderExchange)
                .with("order.routing.key");
    }
}

6.3 消息生产者

@Service
@Slf4j
public class OrderProducer {
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    public void sendOrder(Order order) {
        try {
            rabbitTemplate.convertAndSend("order.exchange", "order.routing.key", order);
            log.info("订单消息发送成功: {}", order.getId());
        } catch (Exception e) {
            log.error("订单消息发送失败", e);
        }
    }
}

6.4 消息消费者

@Component
@Slf4j
public class OrderConsumer {
    
    @RabbitListener(queues = "order.queue")
    public void processOrder(Order order) {
        try {
            log.info("收到订单消息: {}", order.getId());
            // 异步处理订单逻辑
            processOrderAsync(order);
        } catch (Exception e) {
            log.error("订单处理失败", e);
        }
    }
    
    private void processOrderAsync(Order order) {
        // 具体的订单处理逻辑
    }
}

6.5 消息确认机制

@Configuration
public class RabbitMQConfirmConfig {
    
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        
        // 消息发送到交换机确认
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (!ack) {
                log.error("消息发送到交换机失败: {}", cause);
            }
        });
        
        // 消息从交换机路由到队列确认
        rabbitTemplate.setReturnsCallback(returned -> {
            log.error("消息从交换机路由到队列失败: {}", returned);
        });
        
        return rabbitTemplate;
    }
}

7. 最佳实践

7.1 异常处理

  • 使用@Async时要注意异常处理
  • 为异步方法返回Future或CompletableFuture以便跟踪执行状态
  • 实现AsyncUncaughtExceptionHandler处理未捕获的异常
  • MQ消费者要做好消息重试和死信队列处理

7.2 线程池配置

  • 根据业务需求合理配置线程池参数
  • 为不同业务场景配置不同的线程池
  • 监控线程池状态,避免资源耗尽

7.3 性能优化

  • 合理使用响应式编程,避免过度使用
  • 注意内存泄漏问题
  • 实现优雅停机机制
  • MQ消息要控制大小,避免消息堆积

7.4 消息队列使用建议

  • 选择合适的消息投递模式(同步/异步)
  • 实现消息幂等性处理
  • 合理设置消息过期时间
  • 监控消息积压情况
  • 实现消息追踪机制

8. 总结

SpringBoot 3提供了丰富的异步编程支持,从简单的@Async注解到响应式编程,再到事件驱动模型和消息队列,开发者可以根据具体需求选择合适的方案。在实际应用中,需要注意异常处理、资源管理和性能优化等方面的问题。

消息队列作为一种重要的异步处理方式,特别适合处理耗时操作、削峰填谷以及系统解耦。在使用时需要注意消息的可靠性投递、幂等性处理以及性能监控等方面的问题。

参考资料

  1. Spring官方文档
  2. Spring WebFlux文档
  3. Java CompletableFuture API文档
  4. Spring AMQP文档
  5. RabbitMQ官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/923603.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法新篇章:AI如何在数学领域超越人类

人工智能咨询培训老师叶梓 转载标明出处 尽管大模型在很多领域表现出色&#xff0c;比如理解自然语言和生成文本&#xff0c;但它们在解决一些复杂的推理任务时&#xff0c;比如数学问题、编程挑战或者医疗诊断&#xff0c;还是显得有些力不从心。最近&#xff0c;一个来自中国…

MTK主板_安卓主板方案_MTK联发科主板定制开发

联发科(MTK)主板以其强大的性能和多样化的功能而受到广泛关注。该平台包括多个型号&#xff0c;例如MT6761、MT8766、MT6762、MT6765、MT8768和MT8788等&#xff0c;均配置了四核或八核64位处理器&#xff0c;主频可高达2.0GHz。采用先进的12nm工艺&#xff0c;搭载Android 11.…

windows安全中心,永久卸载工具分享

使用方法 2024Goby红队版工具分享&#xff0c;附2024年漏洞POC下载 下载链接&#xff1a; https://pan.quark.cn/s/4fc2712a2afc一路回车&#xff0c;选项Y即可 耐心等待几秒种&#xff0c;自动重启 此时打开windows安全中心&#xff0c;已经完全不能使用了&#xff0c;响应…

css—轮播图实现

一、背景 最近和朋友在一起讨论的时候&#xff0c;我们提出了这样的一个提问&#xff0c;难道轮播图的效果只能通过js来实现吗&#xff1f;经过我们的一系列的争论&#xff0c;发现了这是可以通过纯css来实现这一效果的&#xff0c;CSS轮播图也是一种常见的网页展示方式&#x…

使用Python和Pybind11调用C++程序(CMake编译)

目录 一、前言二、安装 pybind11三、编写C示例代码四、结合Pybind11和CMake编译C工程五、Python调用动态库六、参考 一、前言 跨语言调用能对不同计算机语言进行互补&#xff0c;本博客主要介绍如何实现Python调用C语言编写的函数。 实验环境&#xff1a; Linux gnuPython3.10…

设计模式之 责任链模式

责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;旨在将多个处理对象通过链式结构连接起来&#xff0c;形成一条处理请求的链条。每个处理对象都有机会处理请求&#xff0c;或者将请求传递给链中的下一个对象。这样&#x…

EXTI配置流程 含中断延时消抖点亮小灯

如图可知&#xff0c;配置流程分成以下一个部分 ①使能GPIO时钟 __HAL_RCC_GPIOA_CLK_ENABLE();// 打开时钟 ②初始化利用 HAL_GPIO_Init 一步到位&#xff0c;可以初始化外设GPIO的一切 4个参数 &#xff08;引脚 Pull 这里选择的模式是从下面这几个里面选 速度&#x…

Scrapy图解工作流程-cnblog

1.1 介绍部分&#xff1a; 文字提到常用的Web框架有Django和Flask&#xff0c;接下来将学习一个全球范围内流行的爬虫框架Scrapy。 1.2 内容部分&#xff1a; Scrapy的概念、作用和工作流程 Scrapy的入门使用 Scrapy构造并发送请求 Scrapy模拟登陆 Scrapy管道的使用 Scrapy中…

string类部分(C++)

目录 1. string类 1.1 auto和范围for auto关键词&#xff1a; 范围for&#xff1a; 1.2 string类的常用接口说明 a&#xff09;string类对象的常见构造 b&#xff09; string类对象的容量操作 size与length&#xff1a; capacity: empty: clear: reserve: 1.reserve&am…

实现一个可配置的TCP设备模拟器,支持交互和解析配置

前言 诸位在做IOT开发的时候是否有遇到一个问题&#xff0c;那就是模拟一个设备来联调测试&#xff0c;虽然说现在的物联网通信主要是用mqtt通信&#xff0c;但还是有很多设备使用TCP这种协议交互&#xff0c;例如充电桩&#xff0c;还有一些工业设备&#xff0c;TCP这类报文交…

Redis主从架构

Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的键值对存储系统&#xff0c;广泛应用于缓存、消息队列、实时分析等场景。为了提高系统的可用性、可靠性和读写性能&#xff0c;Redis提供了主从复制&#xff08;Master-Slave Replication&#xf…

Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导 一、前言 在充满活力与激情的校园生活中&#xff0c;校运会不仅是…

软件团队的共担责任

问责制被认为是个人与其社会系统之间的纽带&#xff0c;它创造了一种将个人与其行为和绩效联系起来的身份关系。在入门系列的第一篇文章《超越工具和流程&#xff1a;成功软件开发团队的策略》中&#xff0c;我们介绍了问责制的概念&#xff0c;并提出了以下定义&#xff1a; …

学习日记_20241126_聚类方法(谱聚类Spectral Clustering)

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…

如何使用Jest测试你的React组件

在本文中&#xff0c;我们将了解如何使用Jest&#xff08;Facebook 维护的一个测试框架&#xff09;来测试我们的React组件。我们将首先了解如何在纯 JavaScript 函数上使用 Jest&#xff0c;然后再了解它提供的一些开箱即用的功能&#xff0c;这些功能专门用于使测试 React 应…

硬菜!高精度!BO-Transformer贝叶斯优化编码器多特征分类预测/故障诊断

硬菜&#xff01;高精度&#xff01;BO-Transformer贝叶斯优化编码器多特征分类预测/故障诊断 目录 硬菜&#xff01;高精度&#xff01;BO-Transformer贝叶斯优化编码器多特征分类预测/故障诊断效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现BO-Transform…

仿真学习 | Abaqus版本差异详解:哪版更适合你的仿真作业?

​ 引言 在上一篇文章《仿真学习 | Fluent版本迭代一览及选择指南》中&#xff0c;我们深入探讨了Fluent的不同版本以及如何根据自身需求选择最合适的版本。今天&#xff0c;我们将把视线聚焦于Abaqus——另一款在工程仿真领域中备受推崇的软件。 在有限元分析领域&#xff0c;…

NLP论文速读(剑桥大学出品)|分解和利用专家模型中的偏好进行改进视觉模型的可信度

论文速读|Decompose and Leverage Preferences from Expert Models for Improving Trustworthiness of MLLMs 论文信息&#xff1a; 简介&#xff1a; 本文探讨的背景是多模态大型语言模型&#xff08;MLLMs&#xff09;&#xff0c;这类模型通过结合视觉特征和文本空间来增强语…

IntelliJ IDEA 中,自动导包功能

在 IntelliJ IDEA 中&#xff0c;自动导包功能可以极大地提高开发效率&#xff0c;减少手动导入包所带来的繁琐和错误。以下是如何在 IntelliJ IDEA 中设置和使用自动导包功能的详细步骤&#xff1a; 一、设置自动导包 打开 IntelliJ IDEA&#xff1a; 启动 IntelliJ IDEA 并打…

红外小目标检测

目录 背景概述算法原理演示效果核心逻辑 使用方式基础镜像配置环境直接运行 参考文献 文章声明&#xff0c;非广告&#xff0c;仅个人体验。 背景 红外图像在许多领域中都有所应用。例如军事领域中&#xff0c;经常需要通过红外成像设备对远距离的目标进行侦察和监视&#xff…