From 54e2df2e0e0ea9b727b9bf222a1852568433629e Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Fri, 13 Mar 2020 16:02:42 +0100 Subject: [PATCH] Improve RouterFunction composition This commit changes the way two RouterFunctions are composed in WebFlux.fn. Prior to this commit, two were composed with `switchIfEmpty()`, switching from the first to the second route if the first did not provide an element. After this commit, two router functions are compose using `concat`, which results in a smaller stack trace. See gh-24652 --- .../reactive/function/server/RouterFunctions.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java index 9eb309c530..85e6ee1e20 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import java.util.function.Supplier; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.core.io.Resource; @@ -778,8 +779,8 @@ public abstract class RouterFunctions { @Override public Mono> route(ServerRequest request) { - return this.first.route(request) - .switchIfEmpty(Mono.defer(() -> this.second.route(request))); + return Flux.concat(this.first.route(request), Mono.defer(() -> this.second.route(request))) + .next(); } @Override @@ -808,9 +809,9 @@ public abstract class RouterFunctions { @Override public Mono> route(ServerRequest request) { - return this.first.route(request) - .map(this::cast) - .switchIfEmpty(Mono.defer(() -> this.second.route(request).map(this::cast))); + return Flux.concat(this.first.route(request), Mono.defer(() -> this.second.route(request))) + .next() + .map(this::cast); } @SuppressWarnings("unchecked")