From 4fbba931a58b57301a59f65ec3d11697d1c30b47 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Fri, 13 Mar 2020 16:26:15 +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 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 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 9068ff7b32..9b869c5ba8 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-2018 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; @@ -486,7 +487,7 @@ public abstract class RouterFunctions { * {@code OrderController.routerFunction()}. * to the {@code changeUser} method in {@code userController}: *
-		 * RouterFunctionlt;ServerResponsegt; route =
+		 * RouterFunction<ServerResponse> route =
 		 *   RouterFunctions.route()
 		 *     .GET("/users", userController::listUsers)
 		 *     .add(orderController.routerFunction());
@@ -803,8 +804,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
@@ -833,9 +834,9 @@ public abstract class RouterFunctions {
 
 		@Override
 		public Mono> route(ServerRequest request) {
-			return this.first.route(request)
-					.map(RouterFunctions::cast)
-					.switchIfEmpty(Mono.defer(() -> this.second.route(request).map(RouterFunctions::cast)));
+			return Flux.concat(this.first.route(request), Mono.defer(() -> this.second.route(request)))
+					.next()
+					.map(RouterFunctions::cast);
 		}
 
 		@Override