|
|
|
@ -16,6 +16,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.http.client; |
|
|
|
package org.springframework.http.client; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.io.Closeable; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.net.URI; |
|
|
|
import java.net.URI; |
|
|
|
|
|
|
|
|
|
|
|
@ -49,7 +50,7 @@ import org.springframework.util.Assert; |
|
|
|
public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsClientHttpRequestFactory |
|
|
|
public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsClientHttpRequestFactory |
|
|
|
implements AsyncClientHttpRequestFactory, InitializingBean { |
|
|
|
implements AsyncClientHttpRequestFactory, InitializingBean { |
|
|
|
|
|
|
|
|
|
|
|
private CloseableHttpAsyncClient httpAsyncClient; |
|
|
|
private HttpAsyncClient asyncClient; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -57,49 +58,98 @@ public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsC |
|
|
|
* with a default {@link HttpAsyncClient} and {@link HttpClient}. |
|
|
|
* with a default {@link HttpAsyncClient} and {@link HttpClient}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public HttpComponentsAsyncClientHttpRequestFactory() { |
|
|
|
public HttpComponentsAsyncClientHttpRequestFactory() { |
|
|
|
this(HttpAsyncClients.createSystem()); |
|
|
|
super(); |
|
|
|
|
|
|
|
this.asyncClient = HttpAsyncClients.createSystem(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} |
|
|
|
* Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} |
|
|
|
* with the given {@link HttpAsyncClient} instance and a default {@link HttpClient}. |
|
|
|
* with the given {@link HttpAsyncClient} instance and a default {@link HttpClient}. |
|
|
|
* @param httpAsyncClient the HttpAsyncClient instance to use for this request factory |
|
|
|
* @param asyncClient the HttpAsyncClient instance to use for this request factory |
|
|
|
|
|
|
|
* @since 4.3.10 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public HttpComponentsAsyncClientHttpRequestFactory(HttpAsyncClient asyncClient) { |
|
|
|
|
|
|
|
super(); |
|
|
|
|
|
|
|
setAsyncClient(asyncClient); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} |
|
|
|
|
|
|
|
* with the given {@link CloseableHttpAsyncClient} instance and a default {@link HttpClient}. |
|
|
|
|
|
|
|
* @param asyncClient the CloseableHttpAsyncClient instance to use for this request factory |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public HttpComponentsAsyncClientHttpRequestFactory(CloseableHttpAsyncClient httpAsyncClient) { |
|
|
|
public HttpComponentsAsyncClientHttpRequestFactory(CloseableHttpAsyncClient asyncClient) { |
|
|
|
super(); |
|
|
|
super(); |
|
|
|
Assert.notNull(httpAsyncClient, "HttpAsyncClient must not be null"); |
|
|
|
setAsyncClient(asyncClient); |
|
|
|
this.httpAsyncClient = httpAsyncClient; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} |
|
|
|
* Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} |
|
|
|
* with the given {@link HttpClient} and {@link HttpAsyncClient} instances. |
|
|
|
* with the given {@link HttpClient} and {@link HttpAsyncClient} instances. |
|
|
|
* @param httpClient the HttpClient instance to use for this request factory |
|
|
|
* @param httpClient the HttpClient instance to use for this request factory |
|
|
|
* @param httpAsyncClient the HttpAsyncClient instance to use for this request factory |
|
|
|
* @param asyncClient the HttpAsyncClient instance to use for this request factory |
|
|
|
|
|
|
|
* @since 4.3.10 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public HttpComponentsAsyncClientHttpRequestFactory(HttpClient httpClient, HttpAsyncClient asyncClient) { |
|
|
|
|
|
|
|
super(httpClient); |
|
|
|
|
|
|
|
setAsyncClient(asyncClient); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Create a new instance of the {@code HttpComponentsAsyncClientHttpRequestFactory} |
|
|
|
|
|
|
|
* with the given {@link CloseableHttpClient} and {@link CloseableHttpAsyncClient} instances. |
|
|
|
|
|
|
|
* @param httpClient the CloseableHttpClient instance to use for this request factory |
|
|
|
|
|
|
|
* @param asyncClient the CloseableHttpAsyncClient instance to use for this request factory |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public HttpComponentsAsyncClientHttpRequestFactory( |
|
|
|
public HttpComponentsAsyncClientHttpRequestFactory( |
|
|
|
CloseableHttpClient httpClient, CloseableHttpAsyncClient httpAsyncClient) { |
|
|
|
CloseableHttpClient httpClient, CloseableHttpAsyncClient asyncClient) { |
|
|
|
|
|
|
|
|
|
|
|
super(httpClient); |
|
|
|
super(httpClient); |
|
|
|
Assert.notNull(httpAsyncClient, "HttpAsyncClient must not be null"); |
|
|
|
setAsyncClient(asyncClient); |
|
|
|
this.httpAsyncClient = httpAsyncClient; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Set the {@code HttpClient} used for |
|
|
|
* Set the {@code HttpAsyncClient} used for |
|
|
|
|
|
|
|
* {@linkplain #createAsyncRequest(URI, HttpMethod) synchronous execution}. |
|
|
|
|
|
|
|
* @since 4.3.10 |
|
|
|
|
|
|
|
* @see #setHttpClient(HttpClient) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void setAsyncClient(HttpAsyncClient asyncClient) { |
|
|
|
|
|
|
|
Assert.notNull(asyncClient, "HttpAsyncClient must not be null"); |
|
|
|
|
|
|
|
this.asyncClient = asyncClient; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Return the {@code HttpAsyncClient} used for |
|
|
|
|
|
|
|
* {@linkplain #createAsyncRequest(URI, HttpMethod) synchronous execution}. |
|
|
|
|
|
|
|
* @since 4.3.10 |
|
|
|
|
|
|
|
* @see #getHttpClient() |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public HttpAsyncClient getAsyncClient() { |
|
|
|
|
|
|
|
return this.asyncClient; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Set the {@code CloseableHttpAsyncClient} used for |
|
|
|
* {@linkplain #createAsyncRequest(URI, HttpMethod) asynchronous execution}. |
|
|
|
* {@linkplain #createAsyncRequest(URI, HttpMethod) asynchronous execution}. |
|
|
|
|
|
|
|
* @deprecated as of 4.3.10, in favor of {@link #setAsyncClient(HttpAsyncClient)} |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setHttpAsyncClient(CloseableHttpAsyncClient httpAsyncClient) { |
|
|
|
@Deprecated |
|
|
|
this.httpAsyncClient = httpAsyncClient; |
|
|
|
public void setHttpAsyncClient(CloseableHttpAsyncClient asyncClient) { |
|
|
|
|
|
|
|
this.asyncClient = asyncClient; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Return the {@code HttpClient} used for |
|
|
|
* Return the {@code CloseableHttpAsyncClient} used for |
|
|
|
* {@linkplain #createAsyncRequest(URI, HttpMethod) asynchronous execution}. |
|
|
|
* {@linkplain #createAsyncRequest(URI, HttpMethod) asynchronous execution}. |
|
|
|
|
|
|
|
* @deprecated as of 4.3.10, in favor of {@link #getAsyncClient()} |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Deprecated |
|
|
|
public CloseableHttpAsyncClient getHttpAsyncClient() { |
|
|
|
public CloseableHttpAsyncClient getHttpAsyncClient() { |
|
|
|
return this.httpAsyncClient; |
|
|
|
Assert.state(this.asyncClient == null || this.asyncClient instanceof CloseableHttpAsyncClient, |
|
|
|
|
|
|
|
"No CloseableHttpAsyncClient - use getAsyncClient() instead"); |
|
|
|
|
|
|
|
return (CloseableHttpAsyncClient) this.asyncClient; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -109,22 +159,26 @@ public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsC |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void startAsyncClient() { |
|
|
|
private void startAsyncClient() { |
|
|
|
CloseableHttpAsyncClient asyncClient = getHttpAsyncClient(); |
|
|
|
HttpAsyncClient asyncClient = getAsyncClient(); |
|
|
|
if (!asyncClient.isRunning()) { |
|
|
|
if (asyncClient instanceof CloseableHttpAsyncClient) { |
|
|
|
asyncClient.start(); |
|
|
|
CloseableHttpAsyncClient closeableAsyncClient = (CloseableHttpAsyncClient) asyncClient; |
|
|
|
|
|
|
|
if (!closeableAsyncClient.isRunning()) { |
|
|
|
|
|
|
|
closeableAsyncClient.start(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException { |
|
|
|
public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException { |
|
|
|
HttpAsyncClient asyncClient = getHttpAsyncClient(); |
|
|
|
|
|
|
|
startAsyncClient(); |
|
|
|
startAsyncClient(); |
|
|
|
|
|
|
|
|
|
|
|
HttpUriRequest httpRequest = createHttpUriRequest(httpMethod, uri); |
|
|
|
HttpUriRequest httpRequest = createHttpUriRequest(httpMethod, uri); |
|
|
|
postProcessHttpRequest(httpRequest); |
|
|
|
postProcessHttpRequest(httpRequest); |
|
|
|
HttpContext context = createHttpContext(httpMethod, uri); |
|
|
|
HttpContext context = createHttpContext(httpMethod, uri); |
|
|
|
if (context == null) { |
|
|
|
if (context == null) { |
|
|
|
context = HttpClientContext.create(); |
|
|
|
context = HttpClientContext.create(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Request configuration not set in the context
|
|
|
|
// Request configuration not set in the context
|
|
|
|
if (context.getAttribute(HttpClientContext.REQUEST_CONFIG) == null) { |
|
|
|
if (context.getAttribute(HttpClientContext.REQUEST_CONFIG) == null) { |
|
|
|
// Use request configuration given by the user, when available
|
|
|
|
// Use request configuration given by the user, when available
|
|
|
|
@ -133,13 +187,14 @@ public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsC |
|
|
|
config = ((Configurable) httpRequest).getConfig(); |
|
|
|
config = ((Configurable) httpRequest).getConfig(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (config == null) { |
|
|
|
if (config == null) { |
|
|
|
config = createRequestConfig(asyncClient); |
|
|
|
config = createRequestConfig(getAsyncClient()); |
|
|
|
} |
|
|
|
} |
|
|
|
if (config != null) { |
|
|
|
if (config != null) { |
|
|
|
context.setAttribute(HttpClientContext.REQUEST_CONFIG, config); |
|
|
|
context.setAttribute(HttpClientContext.REQUEST_CONFIG, config); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return new HttpComponentsAsyncClientHttpRequest(asyncClient, httpRequest, context); |
|
|
|
|
|
|
|
|
|
|
|
return new HttpComponentsAsyncClientHttpRequest(getAsyncClient(), httpRequest, context); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@ -148,7 +203,10 @@ public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsC |
|
|
|
super.destroy(); |
|
|
|
super.destroy(); |
|
|
|
} |
|
|
|
} |
|
|
|
finally { |
|
|
|
finally { |
|
|
|
getHttpAsyncClient().close(); |
|
|
|
HttpAsyncClient asyncClient = getAsyncClient(); |
|
|
|
|
|
|
|
if (asyncClient instanceof Closeable) { |
|
|
|
|
|
|
|
((Closeable) asyncClient).close(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|