Skip to content

Commit 933965b

Browse files
committed
Merge branch '5.3.x'
2 parents bf9f261 + 8c77711 commit 933965b

File tree

4 files changed

+102
-21
lines changed

4 files changed

+102
-21
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/RouterFunctionMapping.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -119,12 +119,11 @@ protected void initRouterFunctions() {
119119
}
120120

121121
private List<RouterFunction<?>> routerFunctions() {
122-
List<RouterFunction<?>> functions = obtainApplicationContext()
122+
return obtainApplicationContext()
123123
.getBeanProvider(RouterFunction.class)
124124
.orderedStream()
125-
.map(router -> (RouterFunction<?>)router)
125+
.map(router -> (RouterFunction<?>) router)
126126
.collect(Collectors.toList());
127-
return (!CollectionUtils.isEmpty(functions) ? functions : Collections.emptyList());
128127
}
129128

130129
private void logRouterFunctions(List<RouterFunction<?>> routerFunctions) {

spring-webflux/src/test/java/org/springframework/web/reactive/function/server/support/RouterFunctionMappingTests.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020
import reactor.core.publisher.Mono;
2121
import reactor.test.StepVerifier;
2222

23+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
2324
import org.springframework.http.codec.ServerCodecConfigurer;
2425
import org.springframework.web.reactive.HandlerMapping;
2526
import org.springframework.web.reactive.function.server.HandlerFunction;
@@ -72,6 +73,23 @@ void noMatch() {
7273
.verify();
7374
}
7475

76+
@Test
77+
void empty() throws Exception {
78+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
79+
context.refresh();
80+
81+
RouterFunctionMapping mapping = new RouterFunctionMapping();
82+
mapping.setMessageReaders(this.codecConfigurer.getReaders());
83+
mapping.setApplicationContext(context);
84+
mapping.afterPropertiesSet();
85+
86+
Mono<Object> result = mapping.getHandler(createExchange("https://example.com/match"));
87+
88+
StepVerifier.create(result)
89+
.expectComplete()
90+
.verify();
91+
}
92+
7593
@Test
7694
void changeParser() throws Exception {
7795
HandlerFunction<ServerResponse> handlerFunction = request -> ServerResponse.ok().build();

spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/RouterFunctionMapping.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,11 +19,10 @@
1919
import java.util.ArrayList;
2020
import java.util.Collections;
2121
import java.util.List;
22-
import java.util.Map;
22+
import java.util.stream.Collectors;
2323

2424
import jakarta.servlet.http.HttpServletRequest;
2525

26-
import org.springframework.beans.factory.BeanFactoryUtils;
2726
import org.springframework.beans.factory.InitializingBean;
2827
import org.springframework.context.ApplicationContext;
2928
import org.springframework.core.SpringProperties;
@@ -135,7 +134,7 @@ public void setDetectHandlerFunctionsInAncestorContexts(boolean detectHandlerFun
135134
@Override
136135
public void afterPropertiesSet() throws Exception {
137136
if (this.routerFunction == null) {
138-
initRouterFunction();
137+
initRouterFunctions();
139138
}
140139
if (CollectionUtils.isEmpty(this.messageConverters)) {
141140
initMessageConverters();
@@ -154,20 +153,23 @@ public void afterPropertiesSet() throws Exception {
154153
* Detect a all {@linkplain RouterFunction router functions} in the
155154
* current application context.
156155
*/
157-
@SuppressWarnings({"rawtypes", "unchecked"})
158-
private void initRouterFunction() {
159-
ApplicationContext applicationContext = obtainApplicationContext();
160-
Map<String, RouterFunction> beans =
161-
(this.detectHandlerFunctionsInAncestorContexts ?
162-
BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RouterFunction.class) :
163-
applicationContext.getBeansOfType(RouterFunction.class));
164-
List<RouterFunction> routerFunctions = new ArrayList<>(beans.values());
156+
private void initRouterFunctions() {
157+
List<RouterFunction<?>> routerFunctions = obtainApplicationContext()
158+
.getBeanProvider(RouterFunction.class)
159+
.orderedStream()
160+
.map(router -> (RouterFunction<?>) router)
161+
.collect(Collectors.toList());
162+
163+
ApplicationContext parentContext = obtainApplicationContext().getParent();
164+
if (parentContext != null && !this.detectHandlerFunctionsInAncestorContexts) {
165+
parentContext.getBeanProvider(RouterFunction.class).stream().forEach(routerFunctions::remove);
166+
}
167+
165168
this.routerFunction = routerFunctions.stream().reduce(RouterFunction::andOther).orElse(null);
166169
logRouterFunctions(routerFunctions);
167170
}
168171

169-
@SuppressWarnings("rawtypes")
170-
private void logRouterFunctions(List<RouterFunction> routerFunctions) {
172+
private void logRouterFunctions(List<RouterFunction<?>> routerFunctions) {
171173
if (mappingsLogger.isDebugEnabled()) {
172174
routerFunctions.forEach(function -> mappingsLogger.debug("Mapped " + function));
173175
}

spring-webmvc/src/test/java/org/springframework/web/servlet/function/support/RouterFunctionMappingTests.java

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,7 +21,10 @@
2121
import java.util.Optional;
2222

2323
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.params.ParameterizedTest;
25+
import org.junit.jupiter.params.provider.ValueSource;
2426

27+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
2528
import org.springframework.http.converter.HttpMessageConverter;
2629
import org.springframework.web.servlet.HandlerExecutionChain;
2730
import org.springframework.web.servlet.HandlerMapping;
@@ -41,7 +44,7 @@
4144
*/
4245
class RouterFunctionMappingTests {
4346

44-
private List<HttpMessageConverter<?>> messageConverters = Collections.emptyList();
47+
private final List<HttpMessageConverter<?>> messageConverters = Collections.emptyList();
4548

4649
@Test
4750
void normal() throws Exception {
@@ -71,6 +74,65 @@ void noMatch() throws Exception {
7174
assertThat(result).isNull();
7275
}
7376

77+
@Test
78+
void empty() throws Exception {
79+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
80+
context.refresh();
81+
82+
RouterFunctionMapping mapping = new RouterFunctionMapping();
83+
mapping.setMessageConverters(this.messageConverters);
84+
mapping.setApplicationContext(context);
85+
mapping.afterPropertiesSet();
86+
87+
MockHttpServletRequest request = createTestRequest("/match");
88+
HandlerExecutionChain result = mapping.getHandler(request);
89+
90+
assertThat(result).isNull();
91+
}
92+
93+
@ParameterizedTest
94+
@ValueSource(booleans = {true, false})
95+
void detectHandlerFunctionsInAncestorContexts(boolean detect) throws Exception {
96+
HandlerFunction<ServerResponse> function1 = request -> ServerResponse.ok().build();
97+
HandlerFunction<ServerResponse> function2 = request -> ServerResponse.ok().build();
98+
HandlerFunction<ServerResponse> function3 = request -> ServerResponse.ok().build();
99+
100+
AnnotationConfigApplicationContext context1 = new AnnotationConfigApplicationContext();
101+
context1.registerBean("fn1", RouterFunction.class, () -> RouterFunctions.route().GET("/fn1", function1).build());
102+
context1.refresh();
103+
104+
AnnotationConfigApplicationContext context2 = new AnnotationConfigApplicationContext();
105+
context2.registerBean("fn2", RouterFunction.class, () -> RouterFunctions.route().GET("/fn2", function2).build());
106+
context2.setParent(context1);
107+
context2.refresh();
108+
109+
AnnotationConfigApplicationContext context3 = new AnnotationConfigApplicationContext();
110+
context3.registerBean("fn3", RouterFunction.class, () -> RouterFunctions.route().GET("/fn3", function3).build());
111+
context3.setParent(context2);
112+
context3.refresh();
113+
114+
RouterFunctionMapping mapping = new RouterFunctionMapping();
115+
mapping.setDetectHandlerFunctionsInAncestorContexts(detect);
116+
mapping.setMessageConverters(this.messageConverters);
117+
mapping.setApplicationContext(context3);
118+
mapping.afterPropertiesSet();
119+
120+
HandlerExecutionChain chain1 = mapping.getHandler(createTestRequest("/fn1"));
121+
HandlerExecutionChain chain2 = mapping.getHandler(createTestRequest("/fn2"));
122+
if (detect) {
123+
assertThat(chain1).isNotNull().extracting(HandlerExecutionChain::getHandler).isSameAs(function1);
124+
assertThat(chain2).isNotNull().extracting(HandlerExecutionChain::getHandler).isSameAs(function2);
125+
}
126+
else {
127+
assertThat(chain1).isNull();
128+
assertThat(chain2).isNull();
129+
}
130+
131+
HandlerExecutionChain chain3 = mapping.getHandler(createTestRequest("/fn3"));
132+
assertThat(chain3).isNotNull().extracting(HandlerExecutionChain::getHandler).isSameAs(function3);
133+
134+
}
135+
74136
@Test
75137
void changeParser() throws Exception {
76138
HandlerFunction<ServerResponse> handlerFunction = request -> ServerResponse.ok().build();

0 commit comments

Comments
 (0)