Spring @Async 与 CompletableFuture
Spring @Async with CompletableFuture
我对这段代码有疑问:
@Async
public CompletableFuture<String> doFoo() {
CompletableFuture<String> fooFuture = new CompletableFuture<>();
try {
String fooResult = longOp();
fooFuture.complete(fooResult);
} catch (Exception e) {
fooFuture.completeExceptionally(e);
}
return fooFuture;
}
问题是:doFoo return fooFuture 仅在 longOp 完成后(正确或异常),因此 returning 已经完成的期货或 Spring 做一些魔术和 returning 在执行 body 之前?如果代码在 longOp() 上阻塞,您将如何表示计算被提供给执行程序?
也许是这个?还有其他方法吗?
@Async
public CompletableFuture<String> doFoo() {
CompletableFuture<String> completableFuture = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
try {
String fooResult = longOp();
completableFuture.complete(fooResult);
} catch (Exception e) {
completableFuture.completeExceptionally(e);
}
});
return completableFuture;
}
Spring 实际上完成了所有幕后工作,因此您不必自己创建 CompletableFuture
。
基本上,添加 @Async
注释是 ,就好像 您调用原始方法(没有注释)一样:
CompletableFuture<User> future = CompletableFuture.runAsync(() -> doFoo());
关于你的第二个问题,为了将它提供给执行程序,你可以在 @Async
注释的 value 中指定执行程序 bean 名称,如下所示:
@Async("myExecutor")
public CompletableFuture<User> findUser(String usernameString) throws InterruptedException {
User fooResult = longOp(usernameString);
return CompletableFuture.completedFuture(fooResult);
}
上面基本上是下面的好像你调用了你原来的方法,比如:
CompletableFuture<User> future = CompletableFuture.runAsync(() -> doFoo(), myExecutor);
以及您将使用该方法返回的 CompletableFuture
执行的所有 exceptionally
逻辑。
我对这段代码有疑问:
@Async
public CompletableFuture<String> doFoo() {
CompletableFuture<String> fooFuture = new CompletableFuture<>();
try {
String fooResult = longOp();
fooFuture.complete(fooResult);
} catch (Exception e) {
fooFuture.completeExceptionally(e);
}
return fooFuture;
}
问题是:doFoo return fooFuture 仅在 longOp 完成后(正确或异常),因此 returning 已经完成的期货或 Spring 做一些魔术和 returning 在执行 body 之前?如果代码在 longOp() 上阻塞,您将如何表示计算被提供给执行程序?
也许是这个?还有其他方法吗?
@Async
public CompletableFuture<String> doFoo() {
CompletableFuture<String> completableFuture = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
try {
String fooResult = longOp();
completableFuture.complete(fooResult);
} catch (Exception e) {
completableFuture.completeExceptionally(e);
}
});
return completableFuture;
}
Spring 实际上完成了所有幕后工作,因此您不必自己创建 CompletableFuture
。
基本上,添加 @Async
注释是 ,就好像 您调用原始方法(没有注释)一样:
CompletableFuture<User> future = CompletableFuture.runAsync(() -> doFoo());
关于你的第二个问题,为了将它提供给执行程序,你可以在 @Async
注释的 value 中指定执行程序 bean 名称,如下所示:
@Async("myExecutor")
public CompletableFuture<User> findUser(String usernameString) throws InterruptedException {
User fooResult = longOp(usernameString);
return CompletableFuture.completedFuture(fooResult);
}
上面基本上是下面的好像你调用了你原来的方法,比如:
CompletableFuture<User> future = CompletableFuture.runAsync(() -> doFoo(), myExecutor);
以及您将使用该方法返回的 CompletableFuture
执行的所有 exceptionally
逻辑。