我是多线程和CompletableFuture
的新手,我想知道是否可以在Spring容器(Spring Boot 2)和@Async
中实现以下方案。
我有几个基本构造一个较大对象的服务,我想看看是否可以使粒度服务异步运行。
我有一个服务(ServiceC
)取决于另一个服务(ServiceA
)的输出,而第三个服务可以独立运行(ServiceB
)。所有其他服务都需要someService
,所以我认为不需要将其设为异步调用。下面是布局:
@Service
public class ServiceA {
@Async
public CompletableFuture<A> doServiceAWork(int id) throws AppException {
return CompletableFuture.completedFuture(getA(id));
}
}
@Service
public class ServiceB {
@Async
public CompletableFuture<B> doServiceBWork(int id) {
return CompletableFuture.completedFuture(getB(id));
}
}
@Service
public class ServiceC {
@Async
public CompletableFuture<C> doServiceCWork(A a) {
return CompletableFuture.completedFuture(getC(a));
}
}
@Service
public class ServiceOrchestration {
// Necessary autorwiring of services
public BigObj constructBigObj(AppObj obj) throw SomeAppException {
int id = someService.getId(obj);
BigObj bigObj = new BigObj();
try {
// Conceptualizing here
CompletableFuture<A> cfA = serviceA.doServiceAWork(id);
CompletableFuture<B> cfB = serviceB.doServiceBWork(id);
// Obviously C depends on A
CompletableFuture<C> cfC = serviceB.doServiceCWork(cfA.get());
CompletableFuture.allOf(cfA, cfB, cfC).join();
bigObj.setA(cfA.get());
bigObj.setB(cfB.get());
bigObj.setC(cfC.get());
} catch (AppException | ExecutionException | InterruptedException e) {
throw new SomeAppException("..", e);
}
return BigObj;
}
}
我的要求如下:
在完成ServiceC
后调用对ServiceA
的异步调用,因为返回的数据应被馈送到ServiceC
以便继续进行
如果对ServiceA
的调用引发异常(AppException
),则需要将该异常传播给调用方-在这种情况下,ServiceOrchestration#constructBigObject()
将按上述方式处理。换句话说,如果serviceA.doServiceAWork(id)
引发异常,则应取消所有其他异步调用,但应在constructBigObj
中引发异常,以便捕获并处理
等待所有异步调用完成,然后构造BigObj
对于第二个要求,我查看了isCompletedExceptionally()
,但不确定例如从哪里调用它。在致电join()
之前?那我怎么得到根异常?
异步链接如何在ServiceA
调用和ServiceC
之间进行工作,这里有调用一个依赖项,同时,我需要两者中的值,例如A
和C
来构造BigObj
?