我开始在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());
}
}
为什么第二个代码不起作用?
答案 0 :(得分:1)
返回类型约束为
void
或Future
它也是further detailed in the reference documentation:
在最简单的情况下,注释可以应用于
void
- 返回方法。[...]
即使是返回值的方法也可以异步调用。但是,此类方法需要具有
Future
类型的返回值。这仍然提供了异步执行的好处,以便调用者可以在调用Future上的get()
之前执行其他任务。
在您的第二个示例中,您的@Async
- 带注释的方法不会返回Future
(或ListenableFuture
和CompletableFuture
,这些方法也受支持)。但是,Spring必须异步运行您的方法。因此,它只能表现为您的方法具有void
返回类型,因此它返回null
。
作为旁注,当您使用@Async
时,您的方法已经异步运行,因此您不应在方法中使用CompletableFuture.supplyAsync()
。您应该只计算结果并将其返回,必要时包含在CompletableFuture.completedFuture()
中。如果您的方法只是组成future(就像您的服务只是组成异步存储库结果),那么您可能不需要@Async
注释。另请参阅the example from the Getting Started guide。