Spring Boot异步编程详解

1. 异步编程概述

异步编程是提高应用性能的重要手段,通过异步处理可以避免阻塞主线程,提高系统的并发处理能力。Spring Boot提供了完整的异步编程解决方案。

1.1 异步编程优势

  • 提高并发性:避免线程阻塞,提高系统吞吐量
  • 改善用户体验:快速响应用户请求
  • 资源利用率:更好地利用系统资源
  • 可扩展性:支持高并发场景

1.2 异步编程模式

  • 回调模式:基于回调函数的异步处理
  • Future模式:基于Future的异步结果获取
  • CompletableFuture模式:基于CompletableFuture的链式异步处理
  • 响应式编程:基于Reactive Streams的响应式处理

1.3 核心依赖

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- Spring Boot Async -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
    <!-- Spring WebFlux -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    
    <!-- Reactor Core -->
    <dependency>
        <groupId>io.projectreactor</groupId>
        <artifactId>reactor-core</artifactId>
    </dependency>
</dependencies>

2. @Async注解

2.1 基础异步方法

package com.example.demo.service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

@Service
public class AsyncService {
    
    // 无返回值异步方法
    @Async
    public void asyncMethod() {
        System.out.println("异步方法执行: " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("异步方法完成: " + Thread.currentThread().getName());
    }
    
    // 有返回值异步方法
    @Async
    public CompletableFuture<String> asyncMethodWithReturn() {
        System.out.println("异步方法执行: " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return CompletableFuture.completedFuture("异步方法结果");
    }
    
    // 基于Future的异步方法
    @Async
    public Future<String> asyncMethodWithFuture() {
        System.out.println("异步方法执行: " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return new AsyncResult<>("异步方法结果");
    }
}

2.2 异步配置

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;

@Configuration
@EnableAsync
public class AsyncConfig {
    
    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("Async-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
    
    @Bean(name = "asyncExecutor")
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(5);
        executor.setQueueCapacity(50);
        executor.setThreadNamePrefix("Async-");
        executor.initialize();
        return executor;
    }
}

2.3 异步异常处理

package com.example.demo.service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;

@Service
public class AsyncExceptionService {
    
    @Async
    public CompletableFuture<String> asyncMethodWithException() {
        System.out.println("异步方法执行: " + Thread.currentThread().getName());
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        // 模拟异常
        if (Math.random() > 0.5) {
            throw new RuntimeException("异步方法异常");
        }
        
        return CompletableFuture.completedFuture("异步方法成功");
    }
    
    @Async
    public CompletableFuture<String> asyncMethodWithTryCatch() {
        try {
            System.out.println("异步方法执行: " + Thread.currentThread().getName());
            Thread.sleep(1000);
            
            if (Math.random() > 0.5) {
                throw new RuntimeException("异步方法异常");
            }
            
            return CompletableFuture.completedFuture("异步方法成功");
        } catch (Exception e) {
            System.err.println("异步方法异常: " + e.getMessage());
            return CompletableFuture.completedFuture("异步方法失败");
        }
    }
}

3. CompletableFuture

3.1 基础CompletableFuture

package com.example.demo.service;

import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

@Service
public class CompletableFutureService {
    
    private final Executor executor = Executors.newFixedThreadPool(5);
    
    // 创建CompletableFuture
    public CompletableFuture<String> createCompletableFuture() {
        return CompletableFuture.supplyAsync(() -> {
            System.out.println("CompletableFuture执行: " + Thread.currentThread().getName());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "CompletableFuture结果";
        }, executor);
    }
    
    // 链式处理
    public CompletableFuture<String> chainCompletableFuture() {
        return CompletableFuture
                .supplyAsync(() -> "Hello", executor)
                .thenApply(s -> s + " World")
                .thenApply(s -> s + "!")
                .thenApply(String::toUpperCase);
    }
    
    // 异常处理
    public CompletableFuture<String> handleException() {
        return CompletableFuture
                .supplyAsync(() -> {
                    if (Math.random() > 0.5) {
                        throw new RuntimeException("随机异常");
                    }
                    return "成功结果";
                }, executor)
                .handle((result, throwable) -> {
                    if (throwable != null) {
                        return "异常处理: " + throwable.getMessage();
                    }
                    return result;
                });
    }
}

3.2 组合CompletableFuture

package com.example.demo.service;

import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

@Service
public class CompletableFutureCombineService {
    
    private final Executor executor = Executors.newFixedThreadPool(5);
    
    // 组合两个CompletableFuture
    public CompletableFuture<String> combineTwoFutures() {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "结果1";
        }, executor);
        
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "结果2";
        }, executor);
        
        return future1.thenCombine(future2, (result1, result2) -> 
            "组合结果: " + result1 + " + " + result2);
    }
    
    // 等待所有CompletableFuture完成
    public CompletableFuture<String> waitForAllFutures() {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "结果1";
        }, executor);
        
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "结果2";
        }, executor);
        
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "结果3";
        }, executor);
        
        return CompletableFuture.allOf(future1, future2, future3)
                .thenApply(v -> "所有任务完成: " + future1.join() + ", " + future2.join() + ", " + future3.join());
    }
    
    // 等待任意一个CompletableFuture完成
    public CompletableFuture<String> waitForAnyFuture() {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "结果1";
        }, executor);
        
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "结果2";
        }, executor);
        
        return CompletableFuture.anyOf(future1, future2)
                .thenApply(result -> "任意一个任务完成: " + result);
    }
}

4. 响应式编程

4.1 WebFlux基础

package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    // 获取单个用户
    @GetMapping("/{id}")
    public Mono<User> getUserById(@PathVariable Long id) {
        return userService.findById(id);
    }
    
    // 获取所有用户
    @GetMapping
    public Flux<User> getAllUsers() {
        return userService.findAll();
    }
    
    // 创建用户
    @PostMapping
    public Mono<User> createUser(@RequestBody User user) {
        return userService.save(user);
    }
    
    // 更新用户
    @PutMapping("/{id}")
    public Mono<User> updateUser(@PathVariable Long id, @RequestBody User user) {
        return userService.update(id, user);
    }
    
    // 删除用户
    @DeleteMapping("/{id}")
    public Mono<Void> deleteUser(@PathVariable Long id) {
        return userService.deleteById(id);
    }
}

4.2 响应式服务

package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    // 查找单个用户
    public Mono<User> findById(Long id) {
        return Mono.fromCallable(() -> userRepository.findById(id).orElse(null))
                .subscribeOn(Schedulers.boundedElastic());
    }
    
    // 查找所有用户
    public Flux<User> findAll() {
        return Flux.fromIterable(userRepository.findAll())
                .subscribeOn(Schedulers.boundedElastic());
    }
    
    // 保存用户
    public Mono<User> save(User user) {
        return Mono.fromCallable(() -> userRepository.save(user))
                .subscribeOn(Schedulers.boundedElastic());
    }
    
    // 更新用户
    public Mono<User> update(Long id, User user) {
        return Mono.fromCallable(() -> {
            user.setId(id);
            return userRepository.save(user);
        }).subscribeOn(Schedulers.boundedElastic());
    }
    
    // 删除用户
    public Mono<Void> deleteById(Long id) {
        return Mono.fromRunnable(() -> userRepository.deleteById(id))
                .subscribeOn(Schedulers.boundedElastic())
                .then();
    }
}

4.3 响应式流处理

package com.example.demo.service;

import com.example.demo.entity.User;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import java.time.Duration;
import java.util.List;

@Service
public class ReactiveStreamService {
    
    // 流式处理
    public Flux<String> processStream() {
        return Flux.range(1, 10)
                .map(i -> "处理数据: " + i)
                .delayElements(Duration.ofMillis(100))
                .subscribeOn(Schedulers.parallel());
    }
    
    // 背压处理
    public Flux<String> handleBackpressure() {
        return Flux.range(1, 1000)
                .map(i -> "数据: " + i)
                .onBackpressureBuffer(100) // 缓冲100个元素
                .subscribeOn(Schedulers.parallel());
    }
    
    // 错误处理
    public Flux<String> handleErrors() {
        return Flux.range(1, 10)
                .map(i -> {
                    if (i == 5) {
                        throw new RuntimeException("处理异常");
                    }
                    return "数据: " + i;
                })
                .onErrorResume(throwable -> Flux.just("错误处理: " + throwable.getMessage()))
                .subscribeOn(Schedulers.parallel());
    }
    
    // 超时处理
    public Mono<String> handleTimeout() {
        return Mono.fromCallable(() -> {
            Thread.sleep(2000);
            return "处理完成";
        })
        .timeout(Duration.ofSeconds(1))
        .onErrorReturn("处理超时")
        .subscribeOn(Schedulers.boundedElastic());
    }
}

5. 异步任务调度

5.1 定时任务

package com.example.demo.service;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Service
public class ScheduledService {
    
    // 固定延迟执行
    @Scheduled(fixedDelay = 5000)
    public void fixedDelayTask() {
        System.out.println("固定延迟任务执行: " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME));
    }
    
    // 固定频率执行
    @Scheduled(fixedRate = 3000)
    public void fixedRateTask() {
        System.out.println("固定频率任务执行: " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME));
    }
    
    // Cron表达式执行
    @Scheduled(cron = "0 0 12 * * ?")
    public void cronTask() {
        System.out.println("Cron任务执行: " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME));
    }
    
    // 初始延迟执行
    @Scheduled(initialDelay = 10000, fixedRate = 5000)
    public void initialDelayTask() {
        System.out.println("初始延迟任务执行: " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME));
    }
}

5.2 任务调度配置

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.concurrent.Executor;

@Configuration
@EnableScheduling
public class SchedulingConfig {
    
    @Bean
    public Executor taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5);
        scheduler.setThreadNamePrefix("Scheduled-");
        scheduler.setWaitForTasksToCompleteOnShutdown(true);
        scheduler.setAwaitTerminationSeconds(60);
        scheduler.initialize();
        return scheduler;
    }
}

6. 异步消息处理

6.1 消息队列异步处理

package com.example.demo.service;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;

@Service
public class AsyncMessageService {
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    // 发送异步消息
    public void sendAsyncMessage(String message) {
        CompletableFuture.runAsync(() -> {
            rabbitTemplate.convertAndSend("async.exchange", "async.routing.key", message);
        });
    }
    
    // 异步处理消息
    @RabbitListener(queues = "async.queue")
    public void handleAsyncMessage(String message) {
        System.out.println("异步处理消息: " + message);
        
        // 模拟异步处理
        CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(2000);
                System.out.println("消息处理完成: " + message);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
    }
}

6.2 事件驱动异步处理

package com.example.demo.service;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;

@Service
public class EventDrivenAsyncService {
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    // 发布异步事件
    public void publishAsyncEvent(String data) {
        AsyncEvent event = new AsyncEvent(this, data);
        eventPublisher.publishEvent(event);
    }
    
    // 异步处理事件
    @EventListener
    @Async
    public CompletableFuture<Void> handleAsyncEvent(AsyncEvent event) {
        System.out.println("异步处理事件: " + event.getData());
        
        try {
            Thread.sleep(2000);
            System.out.println("事件处理完成: " + event.getData());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        return CompletableFuture.completedFuture(null);
    }
    
    // 事件类
    public static class AsyncEvent {
        private final Object source;
        private final String data;
        
        public AsyncEvent(Object source, String data) {
            this.source = source;
            this.data = data;
        }
        
        public Object getSource() { return source; }
        public String getData() { return data; }
    }
}

7. 异步性能优化

7.1 线程池优化

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
public class AsyncPerformanceConfig {
    
    @Bean(name = "asyncExecutor")
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(200);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("Async-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        executor.initialize();
        return executor;
    }
    
    @Bean(name = "ioExecutor")
    public Executor ioExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setMaxPoolSize(50);
        executor.setQueueCapacity(500);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("IO-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

7.2 异步监控

package com.example.demo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

@Service
public class AsyncMonitorService {
    
    @Autowired
    private ThreadPoolTaskExecutor asyncExecutor;
    
    public Map<String, Object> getAsyncStats() {
        Map<String, Object> stats = new HashMap<>();
        
        ThreadPoolExecutor executor = asyncExecutor.getThreadPoolExecutor();
        
        stats.put("corePoolSize", executor.getCorePoolSize());
        stats.put("maximumPoolSize", executor.getMaximumPoolSize());
        stats.put("activeCount", executor.getActiveCount());
        stats.put("completedTaskCount", executor.getCompletedTaskCount());
        stats.put("taskCount", executor.getTaskCount());
        stats.put("queueSize", executor.getQueue().size());
        
        return stats;
    }
}

8. 异步最佳实践

8.1 异步方法设计

package com.example.demo.service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@Service
public class AsyncBestPracticeService {
    
    // 异步方法应该返回CompletableFuture
    @Async
    public CompletableFuture<String> asyncMethodWithReturn() {
        try {
            // 模拟异步处理
            Thread.sleep(1000);
            return CompletableFuture.completedFuture("异步处理完成");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return CompletableFuture.failedFuture(e);
        }
    }
    
    // 异步方法应该处理异常
    @Async
    public CompletableFuture<String> asyncMethodWithExceptionHandling() {
        try {
            // 模拟可能失败的操作
            if (Math.random() > 0.5) {
                throw new RuntimeException("随机失败");
            }
            Thread.sleep(1000);
            return CompletableFuture.completedFuture("异步处理成功");
        } catch (Exception e) {
            return CompletableFuture.failedFuture(e);
        }
    }
    
    // 异步方法应该设置超时
    @Async
    public CompletableFuture<String> asyncMethodWithTimeout() {
        return CompletableFuture
                .supplyAsync(() -> {
                    try {
                        Thread.sleep(2000);
                        return "异步处理完成";
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException(e);
                    }
                })
                .orTimeout(1, TimeUnit.SECONDS)
                .exceptionally(throwable -> "异步处理超时");
    }
}

8.2 异步配置最佳实践

# application.yml
spring:
  task:
    execution:
      pool:
        core-size: 10
        max-size: 20
        queue-capacity: 200
        keep-alive: 60s
      thread-name-prefix: "Async-"
    scheduling:
      pool:
        size: 5
      thread-name-prefix: "Scheduled-"

# 异步监控
management:
  endpoints:
    web:
      exposure:
        include: health,metrics,threaddump
  metrics:
    export:
      prometheus:
        enabled: true

9. 总结

Spring Boot异步编程提供了完整的异步处理解决方案:

  1. @Async注解:简单的异步方法声明
  2. CompletableFuture:强大的异步编程工具
  3. 响应式编程:基于Reactive Streams的响应式处理
  4. 任务调度:定时任务和异步任务调度
  5. 消息处理:异步消息队列处理
  6. 性能优化:线程池配置和性能监控
  7. 最佳实践:异步方法设计和配置优化

通过合理使用这些异步编程技术,可以构建出高性能、高并发的Spring Boot应用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小凯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值