@@ -71,59 +71,68 @@ public class ReactorClientHttpRequestFactory implements ClientHttpRequestFactory
71
71
72
72
73
73
/**
74
- * Create a new instance of the {@code ReactorClientHttpRequestFactory}
75
- * with a default {@link HttpClient} that has compression enabled.
74
+ * Constructor with default client, created via {@link HttpClient#create()},
75
+ * and with {@link HttpClient#compress compression} enabled.
76
76
*/
77
77
public ReactorClientHttpRequestFactory () {
78
- this .httpClient = defaultInitializer .apply (HttpClient .create ());
79
- this .resourceFactory = null ;
80
- this .mapper = null ;
78
+ this (defaultInitializer .apply (HttpClient .create ()));
81
79
}
82
80
83
81
/**
84
- * Create a new instance of the {@code ReactorClientHttpRequestFactory}
85
- * based on the given {@link HttpClient}.
86
- * @param httpClient the client to base on
82
+ * Constructor with a given {@link HttpClient} instance.
83
+ * @param client the client to use
87
84
*/
88
- public ReactorClientHttpRequestFactory (HttpClient httpClient ) {
89
- Assert .notNull (httpClient , "HttpClient must not be null" );
90
- this .httpClient = httpClient ;
85
+ public ReactorClientHttpRequestFactory (HttpClient client ) {
86
+ Assert .notNull (client , "HttpClient must not be null" );
91
87
this .resourceFactory = null ;
92
88
this .mapper = null ;
89
+ this .httpClient = client ;
93
90
}
94
91
95
92
/**
96
93
* Constructor with externally managed Reactor Netty resources, including
97
94
* {@link LoopResources} for event loop threads, and {@link ConnectionProvider}
98
- * for the connection pool.
99
- * <p>This constructor should be used only when you don't want the client
100
- * to participate in the Reactor Netty global resources. By default the
101
- * client participates in the Reactor Netty global resources held in
102
- * {@link reactor.netty.http.HttpResources}, which is recommended since
103
- * fixed, shared resources are favored for event loop concurrency. However,
104
- * consider declaring a {@link ReactorResourceFactory} bean with
105
- * {@code globalResources=true} in order to ensure the Reactor Netty global
106
- * resources are shut down when the Spring ApplicationContext is stopped or closed
107
- * and restarted properly when the Spring ApplicationContext is
108
- * (with JVM Checkpoint Restore for example).
109
- * @param resourceFactory the resource factory to obtain the resources from
110
- * @param mapper a mapper for further initialization of the created client
95
+ * for connection pooling.
96
+ * <p>Generally, it is recommended to share resources for event loop
97
+ * concurrency. This can be achieved either by participating in the JVM-wide,
98
+ * global resources held in {@link reactor.netty.http.HttpResources}, or by
99
+ * using a specific, shared set of resources through a
100
+ * {@link ReactorResourceFactory} bean. The latter can ensure that resources
101
+ * are shut down when the Spring ApplicationContext is stopped/closed and
102
+ * restarted again (e.g. JVM checkpoint restore).
103
+ * @param resourceFactory the resource factory to get resources from
104
+ * @param mapper for further initialization of the client
111
105
*/
112
- public ReactorClientHttpRequestFactory (ReactorResourceFactory resourceFactory , Function <HttpClient , HttpClient > mapper ) {
106
+ public ReactorClientHttpRequestFactory (
107
+ ReactorResourceFactory resourceFactory , Function <HttpClient , HttpClient > mapper ) {
108
+
113
109
this .resourceFactory = resourceFactory ;
114
110
this .mapper = mapper ;
115
111
if (resourceFactory .isRunning ()) {
116
112
this .httpClient = createHttpClient (resourceFactory , mapper );
117
113
}
118
114
}
119
115
116
+ private HttpClient createHttpClient (ReactorResourceFactory factory , Function <HttpClient , HttpClient > mapper ) {
117
+ HttpClient client = HttpClient .create (factory .getConnectionProvider ());
118
+ client = defaultInitializer .andThen (mapper ).apply (client );
119
+ client = client .runOn (factory .getLoopResources ());
120
+ if (this .connectTimeout != null ) {
121
+ client = client .option (ChannelOption .CONNECT_TIMEOUT_MILLIS , this .connectTimeout );
122
+ }
123
+ return client ;
124
+ }
125
+
120
126
121
127
/**
122
- * Set the underlying connect timeout in milliseconds.
123
- * A value of 0 specifies an infinite timeout.
124
- * <p>Default is 30 seconds.
128
+ * Set the underlying connect timeout value on the underlying client.
129
+ * Effectively, a shortcut for
130
+ * {@code httpClient.option(CONNECT_TIMEOUT_MILLIS, timeout)}.
131
+ * <p>By default, set to 30 seconds.
132
+ * @param connectTimeout the timeout value in millis; use 0 to never time out.
125
133
* @see HttpClient#option(ChannelOption, Object)
126
134
* @see ChannelOption#CONNECT_TIMEOUT_MILLIS
135
+ * @see <a href="https://projectreactor.io/docs/netty/release/reference/index.html#connection-timeout">Connection Timeout</a>
127
136
*/
128
137
public void setConnectTimeout (int connectTimeout ) {
129
138
Assert .isTrue (connectTimeout >= 0 , "Timeout must be a non-negative value" );
@@ -135,11 +144,7 @@ public void setConnectTimeout(int connectTimeout) {
135
144
}
136
145
137
146
/**
138
- * Set the underlying connect timeout in milliseconds.
139
- * A value of 0 specifies an infinite timeout.
140
- * <p>Default is 30 seconds.
141
- * @see HttpClient#option(ChannelOption, Object)
142
- * @see ChannelOption#CONNECT_TIMEOUT_MILLIS
147
+ * Variant of {@link #setConnectTimeout(int)} with a {@link Duration} value.
143
148
*/
144
149
public void setConnectTimeout (Duration connectTimeout ) {
145
150
Assert .notNull (connectTimeout , "ConnectTimeout must not be null" );
@@ -156,13 +161,11 @@ public void setReadTimeout(long readTimeout) {
156
161
}
157
162
158
163
/**
159
- * Set the underlying read timeout as {@code Duration}.
160
- * <p>Default is 10 seconds.
164
+ * Variant of {@link #setConnectTimeout(int)} with a {@link Duration} value.
161
165
*/
162
166
public void setReadTimeout (Duration readTimeout ) {
163
167
Assert .notNull (readTimeout , "ReadTimeout must not be null" );
164
- Assert .isTrue (!readTimeout .isNegative (), "Timeout must be a non-negative value" );
165
- this .readTimeout = readTimeout ;
168
+ setReadTimeout ((int ) readTimeout .toMillis ());
166
169
}
167
170
168
171
/**
@@ -180,29 +183,20 @@ public void setExchangeTimeout(long exchangeTimeout) {
180
183
*/
181
184
public void setExchangeTimeout (Duration exchangeTimeout ) {
182
185
Assert .notNull (exchangeTimeout , "ExchangeTimeout must not be null" );
183
- Assert .isTrue (!exchangeTimeout .isNegative (), "Timeout must be a non-negative value" );
184
- this .exchangeTimeout = exchangeTimeout ;
185
- }
186
-
187
- private HttpClient createHttpClient (ReactorResourceFactory factory , Function <HttpClient , HttpClient > mapper ) {
188
- HttpClient httpClient = defaultInitializer .andThen (mapper )
189
- .apply (HttpClient .create (factory .getConnectionProvider ()));
190
- httpClient = httpClient .runOn (factory .getLoopResources ());
191
- if (this .connectTimeout != null ) {
192
- httpClient = httpClient .option (ChannelOption .CONNECT_TIMEOUT_MILLIS , this .connectTimeout );
193
- }
194
- return httpClient ;
186
+ setExchangeTimeout ((int ) exchangeTimeout .toMillis ());
195
187
}
196
188
197
189
198
190
@ Override
199
191
public ClientHttpRequest createRequest (URI uri , HttpMethod httpMethod ) throws IOException {
200
- HttpClient httpClient = this .httpClient ;
201
- if (httpClient == null ) {
202
- Assert .state (this .resourceFactory != null && this .mapper != null , "Illegal configuration" );
203
- httpClient = createHttpClient (this .resourceFactory , this .mapper );
192
+ HttpClient client = this .httpClient ;
193
+ if (client == null ) {
194
+ Assert .state (this .resourceFactory != null && this .mapper != null ,
195
+ "Expected HttpClient or ResourceFactory and mapper" );
196
+ client = createHttpClient (this .resourceFactory , this .mapper );
204
197
}
205
- return new ReactorClientHttpRequest (httpClient , uri , httpMethod , this .exchangeTimeout , this .readTimeout );
198
+ return new ReactorClientHttpRequest (
199
+ client , uri , httpMethod , this .exchangeTimeout , this .readTimeout );
206
200
}
207
201
208
202
@@ -237,8 +231,7 @@ public boolean isRunning() {
237
231
238
232
@ Override
239
233
public int getPhase () {
240
- // Start after ReactorResourceFactory
241
- return 1 ;
234
+ return 1 ; // start after ReactorResourceFactory (0)
242
235
}
243
236
244
237
}
0 commit comments