ExchangeFilterFunction выполняет код вне реактивного потока WebClient? - PullRequest
2 голосов
/ 01 апреля 2020

Я создаю ExchangeFilterFunction для расширенной регистрации во время WebClient запросов.

Вопрос: есть ли разница, если я выполню регистрацию внутри функции .doOnNext() в следующем примере? Или они равны в обработке?

ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
    LOGGER.info("Request url=" + clientResponse.url() + ", method=" + clientResponse.method());
    return Mono.just(clientRequest);
});

ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
    return Mono.just(clientRequest).doOnNext(clientResponse2 -> {
        LOGGER.info("Request url=" + clientResponse2.url() + ", method=" + clientResponse2.method());
    });
});

Есть ли какое-то преимущество у одного над другим?

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

Я просто ненавижу любое искусственное введение Mono.just или подобное в ваш поток. Я полагаю, что .doOnNext - это еще один дополнительный шаг, но я не могу себе представить, что это имеет какое-либо значение. Лучше не нарушать поток. Я думаю, что это было бы худшим снижением производительности.

Примечание: при входе в систему WebClient будет регистрироваться, как отмечено ниже, и, как правило, выглядит немного уродливее, чем с использованием вспомогательных методов, но при этом избегается использование * 1006. *.

@Override
public void run(ApplicationArguments args) throws Exception {
    WebClient webClient = WebClient.builder()
            .baseUrl("http://localhost:8080/")
            .filter(eff)
            .build();
    webClient.get().retrieve().bodyToMono(String.class).subscribe(System.out::println);
}

ExchangeFilterFunction eff = (cr,ef)->{
    System.out.println("method: " + cr.method());
    return ef.exchange(cr)
    .map(cresp->{
        System.out.println(cresp.rawStatusCode());
        return cresp;
    });
};
0 голосов
/ 02 апреля 2020

В этом конкретном случае веб-клиент правильно вызовет фильтр. Однако, будьте осторожны с этим в целом.

В первом случае регистрация будет происходить, когда метод вызван . На самом деле это может быть неправильно, если вызывающая сторона никогда не подписывается на возвращенного издателя. Издатель также может быть вызван много раз, как в случае повторной попытки или повтора и т. Д. c. и это тоже будет неправильно.

Во втором случае он будет вызываться каждый раз, когда он подписан на.

public class Foo {

    static Mono<String> echo(String message) {
        System.out.println("echo called with " + message);
        return Mono.just(message);
    }

    static Mono<String> rxEcho(String message) {
        return Mono.just(message).doOnNext(msg -> System.out.println("rxEcho was called with " + msg));
    }

    public static void main(String[] args) {
        //logged, even though never actually called
        echo("no sub");
        //only logs 1 time
        echo("retry")
            .repeat(3)
            .blockLast();

        System.out.println("---------------");

        //never subbed, never logged
        rxEcho("no sub");

        //all 4 calls are logged
        rxEcho("retry")
            .repeat(3)
            .blockLast();
    }
}

Также обратите внимание, что вы не должны звонить Я не хотел путать пример с StepVerifier. Любой вариант block () в реальном коде.

...