【SpringBoot系列】如何优雅地实现异步调用

时间:2024-10-21 13:09:39

文章目录

      • 1.前言
      • 2.同步和异步之间的区别
        • 2.1 执行方式
        • 2.2 阻塞与非阻塞
        • 2.3 返回结果
        • 2.4 资源利用率
        • 2.5 编程模型
      • 3.几种异步的方式
        • 3.1 @Async注解
          • 示例
        • 3.2 CompletableFuture
          • 3.2.1 特点
          • 3.2.2 示例
        • 3.3 Reactor/RxJava
          • 3.3.1 Reactor示例
          • 3.3.2 RxJava示例
        • 3.4 WebFlux
      • 总结
      • 写在最后

579a429daf314744b995f37351b46548

1.前言

在现代的应用程序开发中,异步调用是提高系统性能和响应能力的重要手段之一。

Spring Boot作为一个快速开发框架,提供了多种方式来实现异步调用,使得开发者能够更加优雅地处理并发和异步任务。

本文将介绍如何在Spring Boot中实现异步调用的方法和技巧,帮助开发者更好地利用异步调用提升系统的性能和可扩展性。


2.同步和异步之间的区别

image-20231112074552855

2.1 执行方式

同步是指程序按照顺序依次执行,每个操作完成后再执行下一个操作;

异步是指程序不按照顺序执行,可以同时执行多个操作。

2.2 阻塞与非阻塞

同步操作是阻塞的,即在执行某个操作时,程序会一直等待该操作完成后才能继续执行下一个操作;

异步操作是非阻塞的,即在执行某个操作时,程序可以继续执行其他操作,不需要等待该操作完成。

2.3 返回结果

同步操作会立即返回结果,程序可以直接使用该结果进行后续处理;

异步操作不会立即返回结果,而是通过回调函数、轮询或者事件通知等方式来获取结果。

2.4 资源利用率

同步操作会占用线程资源,每个操作都需要一个线程来执行

异步操作可以充分利用线程资源,一个线程可以同时处理多个操作。

2.5 编程模型

同步操作的编程模型相对简单,代码易于理解和调试;

异步操作的编程模型相对复杂,需要处理回调函数、事件监听等机制。

1_result


3.几种异步的方式

image-20231112074937070

3.1 @Async注解

@Async注解是Spring框架提供的一个注解,用于标识一个方法是异步执行的。

当一个方法被@Async注解修饰后,该方法的执行将会在一个单独的线程中进行,而不会阻塞当前线程。

使用@Async注解需要满足以下条件:

1.在Spring配置文件中开启异步支持,可以通过在配置类上添加@EnableAsync注解或者在配置文件中配置task:annotation-driven/来实现。
2.在需要异步执行的方法上添加@Async注解。

示例
@Service
public class MyService {
    @Async
    public void doSomething() {
        // ...
    }
}

调用doSomething()方法时,会在新的线程中执行,实现异步。

需要注意的是,使用@Async注解时,被注解的方法不能是private或final的,因为Spring需要通过代理来实现异步执行。另外,被注解的方法不能在同一个类中被调用,否则异步执行将失效,因为Spring无法通过代理来实现异步调用。

3.2 CompletableFuture

​ CompletableFuture是Java 8中引入的一个类,用于支持异步编程和处理异步任务的结果。它提供了一种简洁而强大的方式来处理异步操作,可以方便地进行任务的组合、转换和处理

3.2.1 特点

异步执行

CompletableFuture可以通过supplyAsync()或runAsync()方法来异步执行任务,返回一个CompletableFuture对象。

链式操作

CompletableFuture提供了一系列的方法,如thenApply()、thenAccept()、thenRun()等,可以对异步任务的结果进行处理,形成链式操作。

异常处理

CompletableFuture提供了exceptionally()和handle()方法,用于处理异步任务中的异常情况。

组合操作

CompletableFuture提供了一系列的组合方法,如thenCompose()、thenCombine()、allOf()、anyOf()等,可以方便地组合多个异步任务。

等待结果

CompletableFuture提供了一系列的方法,如get()、join()、getNow()等,可以等待异步任务的结果。

3.2.2 示例
import ;

public class CompletableFutureExample {

public static void main(String[] args) {
// 异步执行任务
CompletableFuture<String> future = (() -> {
// 异步任务的逻辑
return "Hello, CompletableFuture!";
});

// 处理异步任务的结果
(result -> {
(result);
});

// 等待异步任务的结果
();
}
}

调用该方法会立即返回一个CompletableFuture,在其他线程中异步执行方法逻辑,最终设置结果。

需要注意的是,CompletableFuture类是线程安全的,可以在多线程环境下使用。

另外,CompletableFuture还提供了一些其他的方法,如whenComplete()、thenCompose()、thenCombine()等,可以根据具体需求选择合适的方法来处理异步任务。

3.3 Reactor/RxJava

​ Reactor和RxJava都是用于支持响应式编程的库,它们提供了一种基于事件流的编程模型,可以方便地处理异步和并发操作。

3.3.1 Reactor示例
import ;

public class ReactorExample {

    public static void main(String[] args) {
        // 创建一个包含1到5的异步序列
        Flux<Integer> flux = (1, 5);

        // 订阅序列并处理元素
        (::println);
    }
}
3.3.2 RxJava示例
import ;

public class RxJavaExample {

    public static void main(String[] args) {
        // 创建一个包含1到5的异步序列
        Observable<Integer> observable = (1, 5);

        // 订阅序列并处理元素
        (::println);
    }
}

需要注意的是,Reactor和RxJava都提供了丰富的操作符和工具,可以进行过滤、转换、组合等操作,以及处理错误和异常情况。可以根据具体需求选择合适的操作符和方法来处理异步和并发操作。

3.4 WebFlux

WebFlux是Spring Framework 5引入的一种响应式编程模型,用于构建高性能、可扩展的Web应用程序。它基于Reactor库,提供了一种非阻塞的、异步的编程方式,可以处理大量并发请求,同时保持低的资源消耗。

WebFlux的核心是基于事件驱动的编程模型,通过使用异步非阻塞的方式处理请求和响应,可以充分利用服务器资源,提高系统的吞吐量和响应速度。它支持多种编程模型,包括函数式编程和反应式流编程,可以根据实际需求选择合适的方式进行开发。

import ;
import ;
import ;
import ;
import ;

@SpringBootApplication
public class WebFluxExampleApplication {

	public static void main(String[] args) {
		(, args);
	}
}

@RestController
class HelloController {
    @GetMapping("/hello")
    public Mono<String> hello() {
    	return ("Hello, WebFlux!");
    }
}

总结

通过本文的介绍,我们了解了在Spring Boot中实现异步调用的多种方式和技巧。

无论是使用@Async注解实现异步方法,还是使用CompletableFuture来处理异步任务,亦或是使用消息队列来实现异步消息处理,Spring Boot都提供了丰富的工具和框架来支持异步调用。

通过合理地运用这些技术,我们可以优雅地处理并发和异步任务,提升系统的性能和可扩展性。


写在最后

感谢您的支持和鼓励! ????????

如果大家对相关文章感兴趣,可以关注公众号"架构殿堂",会持续更新AIGC,系统架构, 分布式, java, GO, python, 游戏相关 等系列文章,一系列干货随时送达!

****-end