16
16
17
17
package org .springframework .boot .web .reactive .context ;
18
18
19
+ import java .util .function .Supplier ;
20
+
21
+ import reactor .core .publisher .Mono ;
22
+
19
23
import org .springframework .beans .BeansException ;
20
24
import org .springframework .beans .factory .support .DefaultListableBeanFactory ;
21
25
import org .springframework .boot .web .context .ConfigurableWebServerApplicationContext ;
22
26
import org .springframework .boot .web .reactive .server .ReactiveWebServerFactory ;
23
27
import org .springframework .boot .web .server .WebServer ;
24
28
import org .springframework .context .ApplicationContextException ;
25
29
import org .springframework .http .server .reactive .HttpHandler ;
30
+ import org .springframework .http .server .reactive .ServerHttpRequest ;
31
+ import org .springframework .http .server .reactive .ServerHttpResponse ;
26
32
import org .springframework .util .StringUtils ;
27
33
28
34
/**
@@ -38,6 +44,8 @@ public class ReactiveWebServerApplicationContext
38
44
39
45
private volatile WebServer webServer ;
40
46
47
+ private volatile DeferredHttpHandler httpHandler ;
48
+
41
49
private String serverNamespace ;
42
50
43
51
/**
@@ -78,6 +86,17 @@ protected void onRefresh() {
78
86
}
79
87
}
80
88
89
+ private void createWebServer () {
90
+ WebServer localServer = this .webServer ;
91
+ if (localServer == null ) {
92
+ DeferredHttpHandler localHandler = new DeferredHttpHandler (
93
+ this ::getHttpHandler );
94
+ this .webServer = getWebServerFactory ().getWebServer (localHandler );
95
+ this .httpHandler = localHandler ;
96
+ }
97
+ initPropertySources ();
98
+ }
99
+
81
100
@ Override
82
101
protected void finishRefresh () {
83
102
super .finishRefresh ();
@@ -93,14 +112,6 @@ protected void onClose() {
93
112
stopAndReleaseReactiveWebServer ();
94
113
}
95
114
96
- private void createWebServer () {
97
- WebServer localServer = this .webServer ;
98
- if (localServer == null ) {
99
- this .webServer = getWebServerFactory ().getWebServer (getHttpHandler ());
100
- }
101
- initPropertySources ();
102
- }
103
-
104
115
/**
105
116
* Returns the {@link WebServer} that was created by the context or {@code null} if
106
117
* the server has not yet been created.
@@ -157,7 +168,12 @@ protected HttpHandler getHttpHandler() {
157
168
158
169
private WebServer startReactiveWebServer () {
159
170
WebServer localServer = this .webServer ;
171
+ DeferredHttpHandler localHandler = this .httpHandler ;
160
172
if (localServer != null ) {
173
+ if (localHandler != null ) {
174
+ localHandler .initialize ();
175
+ this .httpHandler = null ;
176
+ }
161
177
localServer .start ();
162
178
}
163
179
return localServer ;
@@ -186,4 +202,40 @@ public void setServerNamespace(String serverNamespace) {
186
202
this .serverNamespace = serverNamespace ;
187
203
}
188
204
205
+ /**
206
+ * {@link HttpHandler} that defers to a supplied handler which is initialized only
207
+ * when the server starts.
208
+ */
209
+ static class DeferredHttpHandler implements HttpHandler {
210
+
211
+ private Supplier <HttpHandler > factory ;
212
+
213
+ private HttpHandler handler ;
214
+
215
+ DeferredHttpHandler (Supplier <HttpHandler > factory ) {
216
+ this .factory = factory ;
217
+ this .handler = this ::handleUninitialized ;
218
+ }
219
+
220
+ public void initialize () {
221
+ this .handler = this .factory .get ();
222
+ }
223
+
224
+ private Mono <Void > handleUninitialized (ServerHttpRequest request ,
225
+ ServerHttpResponse response ) {
226
+ throw new IllegalStateException (
227
+ "The HttpHandler has not yet been initialized" );
228
+ }
229
+
230
+ @ Override
231
+ public Mono <Void > handle (ServerHttpRequest request , ServerHttpResponse response ) {
232
+ return this .handler .handle (request , response );
233
+ }
234
+
235
+ public HttpHandler getHandler () {
236
+ return this .handler ;
237
+ }
238
+
239
+ }
240
+
189
241
}
0 commit comments