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

重学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官方文档

http://www.kler.cn/a/411211.html

相关文章:

  • 【Java】二叉树:数据海洋中灯塔式结构探秘(上)
  • 4.6 JMeter HTTP信息头管理器
  • 计算机毕业设计Hadoop+Spark音乐推荐系统 音乐预测系统 音乐可视化大屏 音乐爬虫 HDFS hive数据仓库 机器学习 深度学习 大数据毕业设计
  • CANopen多电机控制的性能分析
  • 【面试题】2025年百度校招Java后端面试题
  • 【C#】CancellationTokenSource 为任务或线程提供一种优雅的方式来支持取消操作
  • shell编程第四天(day036)
  • sql server 获取当前日期的时间戳
  • Leetcode105从前序与中序遍历序列构造二叉树
  • tableau-制作30个图表
  • 和数集团业务说明会(南京站)顺利举办
  • Flink Sink的使用
  • 【贪心算法第四弹——376.摆动序列】
  • VisionPro 机器视觉案例 之 凹点检测
  • JAVA面向对象核心部分
  • C++设计模式之组合模式实践原则
  • 在 Mac(ARM 架构)上安装 JDK 8 环境
  • React 第八节组件生命周期钩子-类式组件,函数式组件模拟生命周期用法
  • 2024小迪安全基础入门第七课
  • 【实用技能】使用 DHTMLX Diagram让复杂流程可视化
  • C++11特性(详解)
  • SQL on Hadoop
  • 文心一言与千帆大模型平台的区别:探索百度AI生态的双子星
  • 网络安全:关于SecOC及测试开发实践简介
  • 华硕笔记本电脑用U盘重装windows系统
  • 自动化立体仓库堆垛机货叉故障处理