Как создать универсальную оболочку для любого вызова метода?

#java #spring #generics #project-reactor #spring-reactive

#java #весна #дженерики #проект-реактор #spring-реактивный

Вопрос:

Я хочу создать вспомогательный метод, который может обернуть / преобразовать любой вызов метода синхронизации в асинхронный Mono .

Следующее близко, но показывает ошибку:

 Required type: Mono <T>
Provided: Mono<? extends Callable<? extends T>>
  

Это мой код:

 public <T> Mono<T> wrapAsync(Callable<? extends T> supplier) {
    return Mono.fromCallable(() -> supplier)
            .subscribeOn(Schedulers.boundedElastic());
}

public void run() {
    Mono<Boolean> mono = wrapAsync(() -> syncMethod());
}

private Boolean mySyncMethod() {
    return true; //for testing only
}
  

Комментарии:

1. Если Mono.fromCallable принимает a Callable , то (() -> supplier) это неправильный аргумент (это больше похоже на a Callable<Callable<T>> ).

Ответ №1:

Сначала вы вызываете Mono.fromCallable с вызываемым расширить T>>. Вам нужно изменить вызов следующим образом: Mono.fromCallable(supplier) .

Тогда у вас возникнет проблема, потому что Mono.fromCallable будет выведен Callable<? extend ? extend T> так, что ваш Mono будет Mono<? extend T> вместо Mono<T> . Чтобы избежать этого, два решения:

  1. Измените сигнатуру wrapAsync:
 public <T> Mono<T> wrapAsync(Callable<T> supplier) {
    return Mono.fromCallable(supplier)
            .subscribeOn(Schedulers.boundedElastic());
}
  
  1. Или, если вы хотите сохранить подпись, вам нужно указать тип:
 public <T> Mono<T> wrapAsync(Callable<? extends T> supplier) {
    return Mono.<T>fromCallable(supplier)
            .subscribeOn(Schedulers.boundedElastic());
}
  

Комментарии:

1. Хорошо, да, это имеет смысл. Моя проблема заключалась в том, что я должен был бы предоставить самого поставщика также в качестве лямбда-вызова.