![](/img/trans.png)
[英]If I use thenCompose on a CompletableFuture and assign it do I have 2 CompletableFutures?
[英]How to use CompletableFuture.thenCompose() when returning entities from repositories?
我开始在Spring Boot中使用CompletableFuture
,在某些地方,我看到通常的存储库方法返回CompletableFuture <Entity>
而不是Entity
。
我不知道发生了什么,但是当我在存储库中返回CompletableFuture
实例时,代码可以完美运行。 但是,当我返回实体时,代码无法异步工作,并且始终返回null
。
这是一个例子:
@Service
public class AsyncServiceImpl{
/** .. Init repository instances .. **/
@Async(AsyncConfiguration.TASK_EXECUTOR_SERVICE)
public CompletableFuture<Token> getTokenByUser(Credential credential) {
return userRepository.getUser(credential)
.thenCompose(s -> TokenRepository.getToken(s));
}
}
@Repository
public class UserRepository {
@Async(AsyncConfiguration.TASK_EXECUTOR_REPOSITORY)
public CompletableFuture<User> getUser(Credential credentials) {
return CompletableFuture.supplyAsync(() ->
new User(credentials.getUsername())
);
}
}
@Repository
public class TokenRepository {
@Async(AsyncConfiguration.TASK_EXECUTOR_REPOSITORY)
public CompletableFuture<Token> getToken(User user) {
return CompletableFuture.supplyAsync(() ->
new Token(user.getUserId())
);
}
}
前面的代码可以完美运行,但是后面的代码不能异步运行,结果始终为null
。
@Service
public class AsyncServiceImpl {
/** .. Init repository instances .. **/
@Async(AsyncConfiguration.TASK_EXECUTOR_SERVICE)
public CompletableFuture<Token> requestToken(Credential credential) {
return CompletableFuture.supplyAsync(() -> userRepository.getUser(credential))
.thenCompose(s ->
CompletableFuture.supplyAsync(() -> TokenRepository.getToken(s)));
}
}
@Repository
public class UserRepository {
@Async(AsyncConfiguration.TASK_EXECUTOR_REPOSITORY)
public User getUser(Credential credentials) {
return new User(credentials.getUsername());
}
}
@Repository
public class TokenRepository {
@Async(AsyncConfiguration.TASK_EXECUTOR_SERVICE)
public Token getToken(User user) {
return new Token(user.getUserId());
}
}
为什么第二个代码不起作用?
返回类型被限制为
void
或Future
在最简单的情况下,可以将注释应用于返回
void
方法。[…]
即使返回值的方法也可以异步调用。 但是,要求此类方法具有
Future
类型的返回值。 这仍然提供了异步执行的好处,以便调用者可以在该Future上调用get()
之前执行其他任务。
在第二个示例中, @Async
方法不返回Future
(或也支持的ListenableFuture
和CompletableFuture
)。 但是,Spring必须异步运行您的方法。 因此,它只能表现为您的方法具有void
返回类型,并因此返回null
。
附带说明一下,当您使用@Async
,您的方法将已经异步运行,因此您不应在该方法内部使用CompletableFuture.supplyAsync()
。 您应该只计算结果并将其返回,并在必要时将其包装在CompletableFuture.completedFuture()
。 如果您的方法仅是组成期货(例如,您的服务只是组成异步存储库结果),那么您可能不需要@Async
批注。 另请参阅《入门指南》中的示例 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.