从命令式try-with-resources转换为反应式using,using()



我正试图从使用资源的强制性尝试转变为使用资源的被动尝试,但没有成功。我有下面的一段代码,我想移动。

private final AmazonS3 amazonS3;
private final String bucket;

@Override
public Mono<String> getTemplate(String templateId) {
return Mono.fromCallable(() -> {
S3Object s3Object = amazonS3.getObject(bucket, templateId);
try (s3Object) {
return IOUtils.toString(s3Object.getObjectContent());
}
}).subscribeOn(Schedulers.boundedElastic());
}

我想使用资源结构的反应式try来重写。我的第一次尝试是使用Flux.使用

Flux.using(amazonS3.getObject(bucket, templateId),
s3Object -> Flux.just(IOUtils.toString(s3Object.getObjectContent())),
S3Object::close);

s3Object未作为s3Object进行广播,因此不存在getObjectContent。

然后我看了一眼athttps://projectreactor.io/docs/core/release/reference/我想我可能会使用一次性对象,但是我不知道如何用一次性对象包装S3Object。

有人知道我该怎么做吗?感谢

您所采用的方法无法实现这一点。几乎不可能采用像您在这里看到的那样的阻塞API(AWS SDK v1(,并以某种方式对其进行包装以使其具有响应性。

但是,您可以使用AWS SDK v2(您应该在新的开发中使用它(,它有一个异步S3客户端(S3AsyncClient(,您可以用它返回CompleteableFuture<String>:

CompletableFuture<String> contents = s3AsyncClient
.getObject(GetObjectRequest.builder().build(), new ByteArrayAsyncResponseTransformer<>())
.thenApplyAsync(rb -> rb.asUtf8String());

然后,您可以使用Mono.fromFuture(contents)从上述CompleteableFuture中获得Mono<String>