Skip to content

Commit 89717e1

Browse files
committed
Reactive setup refinements
1 parent 578af59 commit 89717e1

File tree

10 files changed

+118
-122
lines changed

10 files changed

+118
-122
lines changed

spring-web-reactive/src/main/java/org/springframework/web/reactive/DispatcherHandler.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
*
5555
* @author Rossen Stoyanchev
5656
* @author Sebastien Deleuze
57+
* @author Juergen Hoeller
5758
* @since 5.0
5859
*/
5960
public class DispatcherHandler implements WebHandler, ApplicationContextAware {
@@ -159,6 +160,7 @@ private HandlerResultHandler getResultHandler(HandlerResult handlerResult) {
159160
* a {@link org.springframework.web.server.adapter.WebHttpHandlerBuilder}.
160161
* @param applicationContext the application context to find the handler beans in
161162
* @see #DispatcherHandler(ApplicationContext)
163+
* @see org.springframework.web.server.adapter.WebHttpHandlerBuilder#webHandler
162164
*/
163165
public static WebHandler toWebHandler(ApplicationContext applicationContext) {
164166
return new DispatcherHandler(applicationContext);
@@ -167,10 +169,14 @@ public static WebHandler toWebHandler(ApplicationContext applicationContext) {
167169
/**
168170
* Expose a dispatcher-based {@link HttpHandler} for the given application context,
169171
* typically for direct registration with an engine adapter such as
170-
* {@link org.springframework.http.server.reactive.ReactorHttpHandlerAdapter}.
172+
* {@link org.springframework.http.server.reactive.ServletHttpHandlerAdapter}.
171173
* @param applicationContext the application context to find the handler beans in
172174
* @see #DispatcherHandler(ApplicationContext)
173175
* @see HttpWebHandlerAdapter
176+
* @see org.springframework.http.server.reactive.ServletHttpHandlerAdapter
177+
* @see org.springframework.http.server.reactive.ReactorHttpHandlerAdapter
178+
* @see org.springframework.http.server.reactive.RxNettyHttpHandlerAdapter
179+
* @see org.springframework.http.server.reactive.UndertowHttpHandlerAdapter
174180
*/
175181
public static HttpHandler toHttpHandler(ApplicationContext applicationContext) {
176182
return new HttpWebHandlerAdapter(new DispatcherHandler(applicationContext));

spring-web-reactive/src/main/java/org/springframework/web/reactive/function/DefaultRequest.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@ class DefaultRequest implements Request {
4444

4545
private final StrategiesSupplier strategies;
4646

47+
4748
DefaultRequest(ServerWebExchange exchange, StrategiesSupplier strategies) {
4849
this.exchange = exchange;
4950
this.strategies = strategies;
5051
this.headers = new DefaultHeaders();
5152
}
5253

54+
5355
@Override
5456
public HttpMethod method() {
5557
return request().getMethod();
@@ -96,10 +98,8 @@ ServerWebExchange exchange() {
9698
}
9799

98100

99-
100101
private class DefaultHeaders implements Headers {
101102

102-
103103
private HttpHeaders delegate() {
104104
return request().getHeaders();
105105
}
@@ -116,7 +116,8 @@ public List<Charset> acceptCharset() {
116116

117117
@Override
118118
public OptionalLong contentLength() {
119-
return toOptionalLong(delegate().getContentLength());
119+
long value = delegate().getContentLength();
120+
return (value != -1 ? OptionalLong.of(value) : OptionalLong.empty());
120121
}
121122

122123
@Override
@@ -137,18 +138,13 @@ public List<HttpRange> range() {
137138
@Override
138139
public List<String> header(String headerName) {
139140
List<String> headerValues = delegate().get(headerName);
140-
return headerValues != null ? headerValues : Collections.emptyList();
141+
return (headerValues != null ? headerValues : Collections.emptyList());
141142
}
142143

143144
@Override
144145
public HttpHeaders asHttpHeaders() {
145146
return HttpHeaders.readOnlyHttpHeaders(delegate());
146147
}
147-
148-
private OptionalLong toOptionalLong(long value) {
149-
return value != -1 ? OptionalLong.of(value) : OptionalLong.empty();
150-
}
151-
152148
}
153149

154150
}

spring-web-reactive/src/main/java/org/springframework/web/reactive/function/RouterFunctions.java

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,9 @@
4444
*
4545
* @author Arjen Poutsma
4646
* @since 5.0
47-
*
4847
*/
4948
public abstract class RouterFunctions {
5049

51-
private static final HandlerFunction<Void> NOT_FOUND_HANDLER = request -> Response.notFound().build();
52-
5350
/**
5451
* Name of the {@link ServerWebExchange} attribute that contains the {@link Request}.
5552
*/
@@ -59,15 +56,19 @@ public abstract class RouterFunctions {
5956
* Name of the {@link ServerWebExchange} attribute that contains the URI
6057
* templates map, mapping variable names to values.
6158
*/
62-
public static final String URI_TEMPLATE_VARIABLES_ATTRIBUTE = RouterFunctions.class.getName() + ".uriTemplateVariables";
59+
public static final String URI_TEMPLATE_VARIABLES_ATTRIBUTE =
60+
RouterFunctions.class.getName() + ".uriTemplateVariables";
61+
62+
private static final HandlerFunction<Void> NOT_FOUND_HANDLER = request -> Response.notFound().build();
63+
6364

6465
/**
6566
* Route to the given handler function if the given request predicate applies.
66-
*
67-
* @param predicate the predicate to test
67+
* @param predicate the predicate to test
6868
* @param handlerFunction the handler function to route to
69-
* @param <T> the type of the handler function
70-
* @return a routing function that routes to {@code handlerFunction} if {@code predicate} evaluates to {@code true}
69+
* @param <T> the type of the handler function
70+
* @return a routing function that routes to {@code handlerFunction} if
71+
* {@code predicate} evaluates to {@code true}
7172
* @see RequestPredicates
7273
*/
7374
public static <T> RouterFunction<T> route(RequestPredicate predicate, HandlerFunction<T> handlerFunction) {
@@ -79,11 +80,11 @@ public static <T> RouterFunction<T> route(RequestPredicate predicate, HandlerFun
7980

8081
/**
8182
* Route to the given routing function if the given request predicate applies.
82-
*
83-
* @param predicate the predicate to test
83+
* @param predicate the predicate to test
8484
* @param routerFunction the routing function to route to
85-
* @param <T> the type of the handler function
86-
* @return a routing function that routes to {@code routerFunction} if {@code predicate} evaluates to {@code true}
85+
* @param <T> the type of the handler function
86+
* @return a routing function that routes to {@code routerFunction} if
87+
* {@code predicate} evaluates to {@code true}
8788
* @see RequestPredicates
8889
*/
8990
public static <T> RouterFunction<T> subroute(RequestPredicate predicate, RouterFunction<T> routerFunction) {
@@ -102,9 +103,8 @@ public static <T> RouterFunction<T> subroute(RequestPredicate predicate, RouterF
102103
}
103104

104105
/**
105-
* Converts the given {@linkplain RouterFunction routing function} into a {@link HttpHandler}.
106+
* Convert the given {@linkplain RouterFunction routing function} into a {@link HttpHandler}.
106107
* This conversion uses {@linkplain StrategiesSupplier#builder() default strategies}.
107-
*
108108
* <p>The returned {@code HttpHandler} can be adapted to run in
109109
* <ul>
110110
* <li>Servlet 3.1+ using the
@@ -116,18 +116,16 @@ public static <T> RouterFunction<T> subroute(RequestPredicate predicate, RouterF
116116
* <li>Undertow using the
117117
* {@link org.springframework.http.server.reactive.UndertowHttpHandlerAdapter}.</li>
118118
* </ul>
119-
*
120119
* @param routerFunction the routing function to convert
121120
* @return an http handler that handles HTTP request using the given routing function
122121
*/
123122
public static HttpHandler toHttpHandler(RouterFunction<?> routerFunction) {
124-
return toHttpHandler(routerFunction, defaultStrategies());
123+
return toHttpHandler(routerFunction, StrategiesSupplier.withDefaults());
125124
}
126125

127126
/**
128-
* Converts the given {@linkplain RouterFunction routing function} into a {@link HttpHandler},
127+
* Convert the given {@linkplain RouterFunction routing function} into a {@link HttpHandler},
129128
* using the given strategies.
130-
*
131129
* <p>The returned {@code HttpHandler} can be adapted to run in
132130
* <ul>
133131
* <li>Servlet 3.1+ using the
@@ -139,70 +137,60 @@ public static HttpHandler toHttpHandler(RouterFunction<?> routerFunction) {
139137
* <li>Undertow using the
140138
* {@link org.springframework.http.server.reactive.UndertowHttpHandlerAdapter}.</li>
141139
* </ul>
142-
*
143140
* @param routerFunction the routing function to convert
144-
* @param strategies the strategies to use
141+
* @param strategies the strategies to use
145142
* @return an http handler that handles HTTP request using the given routing function
146143
*/
147144
public static HttpHandler toHttpHandler(RouterFunction<?> routerFunction, StrategiesSupplier strategies) {
148-
Assert.notNull(routerFunction, "'routerFunction' must not be null");
149-
Assert.notNull(strategies, "'strategies' must not be null");
145+
Assert.notNull(routerFunction, "RouterFunction must not be null");
146+
Assert.notNull(strategies, "StrategiesSupplier must not be null");
150147

151148
return new HttpWebHandlerAdapter(exchange -> {
152149
Request request = new DefaultRequest(exchange, strategies);
153150
addAttributes(exchange, request);
154-
155151
HandlerFunction<?> handlerFunction = routerFunction.route(request).orElse(notFound());
156152
Response<?> response = handlerFunction.handle(request);
157153
return response.writeTo(exchange, strategies);
158154
});
159155
}
160156

161157
/**
162-
* Converts the given {@code RouterFunction} into a {@code HandlerMapping}.
158+
* Convert the given {@code RouterFunction} into a {@code HandlerMapping}.
163159
* This conversion uses {@linkplain StrategiesSupplier#builder() default strategies}.
164-
*
165160
* <p>The returned {@code HandlerMapping} can be run in a
166161
* {@link org.springframework.web.reactive.DispatcherHandler}.
167-
*
168162
* @param routerFunction the routing function to convert
169163
* @return an handler mapping that maps HTTP request to a handler using the given routing function
170164
* @see org.springframework.web.reactive.function.support.HandlerFunctionAdapter
171165
* @see org.springframework.web.reactive.function.support.ResponseResultHandler
172166
*/
173167
public static HandlerMapping toHandlerMapping(RouterFunction<?> routerFunction) {
174-
return toHandlerMapping(routerFunction, defaultStrategies());
168+
return toHandlerMapping(routerFunction, StrategiesSupplier.withDefaults());
175169
}
176170

177171
/**
178-
* Converts the given {@linkplain RouterFunction routing function} into a {@link HandlerMapping},
172+
* Convert the given {@linkplain RouterFunction routing function} into a {@link HandlerMapping},
179173
* using the given strategies.
180-
*
181174
* <p>The returned {@code HandlerMapping} can be run in a
182175
* {@link org.springframework.web.reactive.DispatcherHandler}.
183-
*
184176
* @param routerFunction the routing function to convert
185-
* @param strategies the strategies to use
177+
* @param strategies the strategies to use
186178
* @return an handler mapping that maps HTTP request to a handler using the given routing function
187179
* @see org.springframework.web.reactive.function.support.HandlerFunctionAdapter
188180
* @see org.springframework.web.reactive.function.support.ResponseResultHandler
189181
*/
190182
public static HandlerMapping toHandlerMapping(RouterFunction<?> routerFunction, StrategiesSupplier strategies) {
191-
Assert.notNull(routerFunction, "'routerFunction' must not be null");
192-
Assert.notNull(strategies, "'strategies' must not be null");
183+
Assert.notNull(routerFunction, "RouterFunction must not be null");
184+
Assert.notNull(strategies, "StrategiesSupplier must not be null");
193185

194186
return exchange -> {
195187
Request request = new DefaultRequest(exchange, strategies);
196188
addAttributes(exchange, request);
197-
198189
Optional<? extends HandlerFunction<?>> route = routerFunction.route(request);
199190
return Mono.justOrEmpty(route);
200191
};
201192
}
202193

203-
private static StrategiesSupplier defaultStrategies() {
204-
return StrategiesSupplier.builder().build();
205-
}
206194

207195
private static void addAttributes(ServerWebExchange exchange, Request request) {
208196
Map<String, Object> attributes = exchange.getAttributes();
@@ -218,4 +206,5 @@ private static <T> HandlerFunction<T> notFound() {
218206
static <T> HandlerFunction<T> cast(HandlerFunction<?> handlerFunction) {
219207
return (HandlerFunction<T>) handlerFunction;
220208
}
209+
221210
}

spring-web-reactive/src/main/java/org/springframework/web/reactive/function/StrategiesSupplier.java

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
* {@link #of(Supplier, Supplier, Supplier)}.
3434
*
3535
* @author Arjen Poutsma
36+
* @author Juergen Hoeller
3637
* @since 5.0
3738
* @see RouterFunctions#toHttpHandler(RouterFunction, StrategiesSupplier)
3839
* @see RouterFunctions#toHandlerMapping(RouterFunction, StrategiesSupplier)
@@ -62,12 +63,35 @@ public interface StrategiesSupplier {
6263
*/
6364
Supplier<Stream<ViewResolver>> viewResolvers();
6465

66+
6567
// Static methods
6668

6769
/**
68-
* Return a new {@code StrategiesSupplier} described by the given supplier functions. All
69-
* provided supplier function parameters can be {@code null} to indicate an empty stream is to
70-
* be returned.
70+
* Return a new {@code StrategiesSupplier} with default initialization.
71+
* @return the new {@code StrategiesSupplier}
72+
*/
73+
static StrategiesSupplier withDefaults() {
74+
return builder().build();
75+
}
76+
77+
/**
78+
* Return a new {@code StrategiesSupplier} based on the given
79+
* {@linkplain ApplicationContext application context}.
80+
* The returned supplier will search for all {@link HttpMessageReader}, {@link HttpMessageWriter},
81+
* and {@link ViewResolver} instances in the given application context and return them for
82+
* {@link #messageReaders()}, {@link #messageWriters()}, and {@link #viewResolvers()}
83+
* respectively.
84+
* @param applicationContext the application context to base the strategies on
85+
* @return the new {@code StrategiesSupplier}
86+
*/
87+
static StrategiesSupplier of(ApplicationContext applicationContext) {
88+
return builder(applicationContext).build();
89+
}
90+
91+
/**
92+
* Return a new {@code StrategiesSupplier} described by the given supplier functions.
93+
* All provided supplier function parameters can be {@code null} to indicate an empty
94+
* stream is to be returned.
7195
* @param messageReaders the supplier function for {@link HttpMessageReader} instances (can be {@code null})
7296
* @param messageWriters the supplier function for {@link HttpMessageWriter} instances (can be {@code null})
7397
* @param viewResolvers the supplier function for {@link ViewResolver} instances (can be {@code null})
@@ -82,34 +106,25 @@ static StrategiesSupplier of(Supplier<Stream<HttpMessageReader<?>>> messageReade
82106
public Supplier<Stream<HttpMessageReader<?>>> messageReaders() {
83107
return checkForNull(messageReaders);
84108
}
85-
86109
@Override
87110
public Supplier<Stream<HttpMessageWriter<?>>> messageWriters() {
88111
return checkForNull(messageWriters);
89112
}
90-
91113
@Override
92114
public Supplier<Stream<ViewResolver>> viewResolvers() {
93115
return checkForNull(viewResolvers);
94116
}
95-
96117
private <T> Supplier<Stream<T>> checkForNull(Supplier<Stream<T>> supplier) {
97118
return supplier != null ? supplier : Stream::empty;
98119
}
99120
};
100121
}
101122

102123

103-
/**
104-
* Return a mutable, empty builder for a {@code StrategiesSupplier}.
105-
* @return the builder
106-
*/
107-
static Builder empty() {
108-
return new DefaultStrategiesSupplierBuilder();
109-
}
124+
// Builder methods
110125

111126
/**
112-
* Return a mutable builder for a {@code StrategiesSupplier} with a default initialization.
127+
* Return a mutable builder for a {@code StrategiesSupplier} with default initialization.
113128
* @return the builder
114129
*/
115130
static Builder builder() {
@@ -127,13 +142,21 @@ static Builder builder() {
127142
* @param applicationContext the application context to base the strategies on
128143
* @return the builder
129144
*/
130-
static Builder applicationContext(ApplicationContext applicationContext) {
131-
Assert.notNull(applicationContext, "'applicationContext' must not be null");
145+
static Builder builder(ApplicationContext applicationContext) {
146+
Assert.notNull(applicationContext, "ApplicationContext must not be null");
132147
DefaultStrategiesSupplierBuilder builder = new DefaultStrategiesSupplierBuilder();
133148
builder.applicationContext(applicationContext);
134149
return builder;
135150
}
136151

152+
/**
153+
* Return a mutable, empty builder for a {@code StrategiesSupplier}.
154+
* @return the builder
155+
*/
156+
static Builder empty() {
157+
return new DefaultStrategiesSupplierBuilder();
158+
}
159+
137160

138161
/**
139162
* A mutable builder for a {@link StrategiesSupplier}.
@@ -166,6 +189,6 @@ interface Builder {
166189
* @return the built strategies
167190
*/
168191
StrategiesSupplier build();
169-
170192
}
193+
171194
}

0 commit comments

Comments
 (0)