在Spring中启用Async方法的主要步骤如下:
1)通过注释Spring Boot Application类,在Spring Boot中启用异步处理 @EnableAsync
Spring Boot Application
Spring Boot
@EnableAsync
2)创建一个ThreadPoolExecutor 在单独的线程中运行异步方法
ThreadPoolExecutor
3)注释方法那需要在用单独的线运行@Async 的注释
在Spring站点的博客文章中对此进行了解释。
我看了一下,然后开始在项目中相应地应用更改。它运行良好,并解决了我们在性能方面遇到的问题。
在那篇博客文章中,通过创建一个带有@Async注释的服务方法来解释Async方法的用法,该服务方法调用了GitHub API。
@Async
Async
GitHub API
在阅读该帖子时,该博客帖子给我留下了深刻的印象:
1)使用异步方法时,方法的返回类型必须为 CompletableFuture
CompletableFuture
2)以下是调用异步服务方法的代码行
调用异步服务方法的代码
在Eclipse中进行调试期间,我能够从第1行转到第2行,而无需等待service方法返回结果。但是page1,对于控件超出第1行之后,如何使用服务方法的返回值填充in中的变量,我感到困惑 。 服务方法如下:
@Async public CompletableFuture<User> findUser(String user) throws InterruptedException { logger.info("Looking up " + user); String url = String.format("https://api.github.com/users/%s", user); User results = restTemplate.getForObject(url, User.class); // Artificial delay of 1s for demonstration purposes Thread.sleep(1000L); return CompletableFuture.completedFuture(results); //IT IS completedFuture }
服务方法未将整个过程封装在CompletableFuture中,而是完成了所有处理,然后最后创建了CompletableFuture来保存结果。那么如何实现异步性呢?
我开始调试。以下是我的观察。
每当使用@Async注释对任何方法进行注释时,Spring都会自动为该类创建一个代理对象,并将该代理注入依赖于该类的其他类中。因此,对异步方法的任何调用都将通过代理进行。
一个类AsyncExecutionInterceptor拦截Async方法调用并创建一个CompletableFuture 对象并返回它。
AsyncExecutionInterceptor
未来发展
现在的问题是这个。由于此拦截器类正在创建CompletableFuture,因此为什么服务方法也需要这样做。服务方法可以只返回对象,而不是将其包装在CompletableFuture中吗?
答案是“否”,因为拦截器实际上是由Spring创建的代理调用的。为了实现方法的异步特性,必须使用CompletableFuture。
但是,对于实际方法和代理中存在的方法,我们不能有不同的返回类型。两者必须具有相同的返回类型。这就是即使服务方法也必须返回包装在CompletedFuture中的值的原因。
CompletedFuture
希望这有助于更好地理解异步方法。
原文链接:http://codingdict.com