繁体   English   中英

从存储库返回实体时如何使用CompletableFuture.thenCompose()?

[英]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());
    }
}

为什么第二个代码不起作用?

根据Spring @Async Javadoc

返回类型被限制为voidFuture

并且在参考文档中也有更详细的说明

在最简单的情况下,可以将注释应用于返回void方法。

[…]

即使返回值的方法也可以异步调用。 但是,要求此类方法具有Future类型的返回值。 这仍然提供了异步执行的好处,以便调用者可以在该Future上调用get()之前执行其他任务。

在第二个示例中, @Async方法不返回Future (或也支持的ListenableFutureCompletableFuture )。 但是,Spring必须异步运行您的方法。 因此,它只能表现为您的方法具有void返回类型,并因此返回null

附带说明一下,当您使用@Async ,您的方法将已经异步运行,因此您不应在该方法内部使用CompletableFuture.supplyAsync() 您应该只计算结果并将其返回,并在必要时将其包装在CompletableFuture.completedFuture() 如果您的方法仅是组成期货(例如,您的服务只是组成异步存储库结果),那么您可能不需要@Async批注。 另请参阅《入门指南》中的示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM