文章目录
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异步编程提供了完整的异步处理解决方案:
- @Async注解:简单的异步方法声明
- CompletableFuture:强大的异步编程工具
- 响应式编程:基于Reactive Streams的响应式处理
- 任务调度:定时任务和异步任务调度
- 消息处理:异步消息队列处理
- 性能优化:线程池配置和性能监控
- 最佳实践:异步方法设计和配置优化
通过合理使用这些异步编程技术,可以构建出高性能、高并发的Spring Boot应用。
4万+

被折叠的 条评论
为什么被折叠?



