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

ops/2025/1/2 4:38:38/

更多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 {@Asyncpublic 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 {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(25);executor.setThreadNamePrefix("AsyncThread-");executor.initialize();return executor;}@Overridepublic 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 {@Autowiredprivate 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@EventListenerpublic 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: localhostport: 5672username: guestpassword: guest

6.2 消息队列配置类

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

6.3 消息生产者

@Service
@Slf4j
public class OrderProducer {@Autowiredprivate 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 {@Beanpublic 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官方文档

http://www.ppmy.cn/ops/146341.html

相关文章

Linux 常用命令 - pwd 【显示当前工作目录】

简介 pwd 命令来源于 “print working directory”&#xff0c;即“打印当前工作目录”。这个命令的最主要功能就是显示当前用户所在的完整目录路径。在实际工作中我们经常会频繁在各个目录下进行切换&#xff0c;为了快速获取当前我们所在的目录&#xff0c;可以使用该命令进…

苍穹外卖day07缓存部分分析

苍穹外卖Day07部分聚焦于缓存功能的实现与优化&#xff0c;通过引入redis缓存机制&#xff0c;结合Spring Cache 注解&#xff0c;降低了数据库负载&#xff0c;提升其响应速度。 以下是清除缓存功能代码&#xff1a; RestController RequestMapping("/admin/dish"…

TCP网络编程(二)—— 服务器端的编写

上篇文章我们学习了TCP的两种编程模式&#xff0c;这篇文章我们将开始编写服务器端的代码。完整代码在文章的最后。 首先&#xff0c;我们需要什么变量&#xff1f; 我们需要服务器端的套接字&#xff08;socket&#xff09;&#xff0c;地址和端口&#xff08;addr&#xff0…

Vue.js组件开发-使用vue-pdf显示PDF

安装vue-pdf‌&#xff1a; 首先&#xff0c;需要在Vue项目中安装vue-pdf。可以使用npm或yarn来安装。 npm install vue-pdf或者 yarn add vue-pdf‌在Vue组件中引入并使用vue-pdf‌&#xff1a; 在Vue组件中引入vue-pdf&#xff0c;并使用<pdf>标签来展示PDF文件。 &…

基于Spring Boot的宠物领养系统的设计与实现(代码+数据库+LW)

摘 要 如今社会上各行各业&#xff0c;都在用属于自己专用的软件来进行工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。互联网的发展&#xff0c;离不开一些新的技术&#xff0c;而新技术的产生往往是为了解决现有问题而产生的。针对于宠物领…

网络爬虫科普:原理、类型、策略与常用工具

网络爬虫科普&#xff1a;原理、类型、策略与常用工具 网络爬虫在当今互联网时代扮演着极为重要的角色&#xff0c;它能帮助我们从海量的网络信息中提取出有价值的数据。以下将从网络爬虫的基本概念、工作流程、类型、搜索策略以及常用工具等方面进行详细科普介绍。 一、网络…

广州大彩串口屏安卓/linux触摸屏四路CVBS输入实现同时显示!

一、适用范围 适合广州大彩A40系列产品 产品型号&#xff1a; 二、概述 CVBS只需要一条线缆即可完成视频信号的传输&#xff0c;具有兼容性强、使用简单、成本低廉等优点。典型分辨率为720x480&#xff08;NTSC制&#xff09;或720x576&#xff08;PAL制&#xff09;。 三、…

界面控件DevExpress v24.2新版亮点 - 支持.NET9、增强跨平台性

DevExpress拥有.NET开发需要的所有平台控件&#xff0c;包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress 今年第一个重要版本v23.1正式发布&#xff0c;该版本拥有众多…