Skip to content

Commit 64f2be3

Browse files
committed
avoid parameter for singleton constructor
Reduce code complexity
1 parent 3f2597e commit 64f2be3

7 files changed

Lines changed: 144 additions & 72 deletions

File tree

aliyun-java-sdk-core/src/main/java/com/aliyuncs/http/HttpClientFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ public static IHttpClient buildClient(IClientProfile profile) {
3737
throw new IllegalStateException(String.format("%s is not assignable from com.aliyuncs.http.IHttpClient", customClientClassName));
3838
}
3939
if (ApacheHttpClient.class.equals(httpClientClass)) {
40-
return ApacheHttpClient.getInstance(clientConfig);
40+
IHttpClient client = ApacheHttpClient.getInstance();
41+
client.init(clientConfig);
42+
return client;
4143
}
4244
Constructor<? extends IHttpClient> constructor = httpClientClass.getConstructor(HttpClientConfig.class);
4345
return constructor.newInstance(clientConfig);

aliyun-java-sdk-core/src/main/java/com/aliyuncs/http/IHttpClient.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.aliyuncs.http;
22

3+
import com.aliyuncs.exceptions.ClientException;
4+
35
import java.io.Closeable;
46
import java.io.IOException;
57
import java.util.concurrent.Future;
68

7-
import com.aliyuncs.exceptions.ClientException;
8-
99
public abstract class IHttpClient implements Closeable {
1010

1111
protected HttpClientConfig clientConfig;
@@ -19,6 +19,10 @@ public IHttpClient(HttpClientConfig clientConfig) throws ClientException {
1919

2020
}
2121

22+
public IHttpClient() {
23+
// do nothing
24+
}
25+
2226
protected abstract void init(HttpClientConfig clientConfig) throws ClientException;
2327

2428
public abstract HttpResponse syncInvoke(HttpRequest apiRequest) throws IOException, ClientException;

aliyun-java-sdk-core/src/main/java/com/aliyuncs/http/clients/ApacheHttpClient.java

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.List;
3838
import java.util.Map;
3939
import java.util.concurrent.*;
40+
import java.util.concurrent.atomic.AtomicBoolean;
4041
import java.util.concurrent.atomic.AtomicInteger;
4142

4243
public class ApacheHttpClient extends IHttpClient {
@@ -50,22 +51,32 @@ public class ApacheHttpClient extends IHttpClient {
5051
private ExecutorService executorService;
5152
private CloseableHttpClient httpClient;
5253
private PoolingHttpClientConnectionManager connectionManager;
54+
private AtomicBoolean initialized = new AtomicBoolean(false);
55+
private CountDownLatch latch = new CountDownLatch(1);
5356

5457
private static volatile ApacheHttpClient client;
5558

59+
/**
60+
* use ApacheHttpClient.getInstance() instead
61+
*/
62+
@Deprecated
5663
public static ApacheHttpClient getInstance(HttpClientConfig config) throws ClientException {
64+
throw new IllegalStateException("use ApacheHttpClient.getInstance() instead");
65+
}
66+
67+
public static ApacheHttpClient getInstance() {
5768
if (client == null) {
5869
synchronized (ApacheHttpClient.class) {
5970
if (client == null) {
60-
client = new ApacheHttpClient(config);
71+
client = new ApacheHttpClient();
6172
}
6273
}
6374
}
6475
return client;
6576
}
6677

67-
private ApacheHttpClient(HttpClientConfig config) throws ClientException {
68-
super(config);
78+
private ApacheHttpClient() {
79+
super();
6980
}
7081

7182
private SSLConnectionSocketFactory createSSLConnectionSocketFactory() throws ClientException {
@@ -114,21 +125,7 @@ private SSLConnectionSocketFactory createSSLConnectionSocketFactory() throws Cli
114125

115126
}
116127

117-
@Override
118-
protected void init(final HttpClientConfig config) throws ClientException {
119-
HttpClientBuilder builder;
120-
if (config.containsExtParam(EXT_PARAM_KEY_BUILDER)) {
121-
builder = (HttpClientBuilder) config.getExtParam(EXT_PARAM_KEY_BUILDER);
122-
} else {
123-
builder = HttpClientBuilder.create();
124-
}
125-
126-
// default request config
127-
RequestConfig defaultConfig = RequestConfig.custom().setConnectTimeout((int) config
128-
.getConnectionTimeoutMillis()).setSocketTimeout((int) config.getReadTimeoutMillis())
129-
.setConnectionRequestTimeout((int) config.getWriteTimeoutMillis()).build();
130-
builder.setDefaultRequestConfig(defaultConfig);
131-
128+
private void initConnectionManager() throws ClientException {
132129
// http
133130
RegistryBuilder<ConnectionSocketFactory> socketFactoryRegistryBuilder = RegistryBuilder.create();
134131
socketFactoryRegistryBuilder.register("http", new PlainConnectionSocketFactory());
@@ -139,18 +136,56 @@ protected void init(final HttpClientConfig config) throws ClientException {
139136

140137
// connPool
141138
connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistryBuilder.build());
142-
connectionManager.setMaxTotal(config.getMaxRequests());
143-
connectionManager.setDefaultMaxPerRoute(config.getMaxRequestsPerHost());
144-
builder.setConnectionManager(connectionManager);
145-
ApacheIdleConnectionCleaner.registerConnectionManager(connectionManager, config.getMaxIdleTimeMillis());
139+
connectionManager.setMaxTotal(clientConfig.getMaxRequests());
140+
connectionManager.setDefaultMaxPerRoute(clientConfig.getMaxRequestsPerHost());
141+
}
142+
143+
private HttpClientBuilder initHttpClientBuilder() {
144+
HttpClientBuilder builder;
145+
if (clientConfig.containsExtParam(EXT_PARAM_KEY_BUILDER)) {
146+
builder = (HttpClientBuilder) clientConfig.getExtParam(EXT_PARAM_KEY_BUILDER);
147+
} else {
148+
builder = HttpClientBuilder.create();
149+
}
150+
return builder;
151+
}
146152

153+
private void initExecutor() {
147154
// async
148-
if (config.getExecutorService() == null) {
149-
executorService = new ThreadPoolExecutor(0, config.getMaxRequests(), DEFAULT_THREAD_KEEP_ALIVE_TIME,
155+
if (clientConfig.getExecutorService() == null) {
156+
executorService = new ThreadPoolExecutor(0, clientConfig.getMaxRequests(), DEFAULT_THREAD_KEEP_ALIVE_TIME,
150157
TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new DefaultAsyncThreadFactory());
151158
} else {
152-
executorService = config.getExecutorService();
159+
executorService = clientConfig.getExecutorService();
153160
}
161+
}
162+
163+
@Override
164+
protected void init(final HttpClientConfig config0) throws ClientException {
165+
if (!initialized.compareAndSet(false, true)) {
166+
try {
167+
latch.await();
168+
} catch (InterruptedException e) {
169+
throw new ClientException("SDK.InitFailed", "Init apacheHttpClient failed", e);
170+
}
171+
return;
172+
}
173+
final HttpClientConfig config = (config0 != null ? config0 : HttpClientConfig.getDefault());
174+
this.clientConfig = config;
175+
176+
HttpClientBuilder builder = initHttpClientBuilder();
177+
178+
// default request config
179+
RequestConfig defaultConfig = RequestConfig.custom().setConnectTimeout((int) config
180+
.getConnectionTimeoutMillis()).setSocketTimeout((int) config.getReadTimeoutMillis())
181+
.setConnectionRequestTimeout((int) config.getWriteTimeoutMillis()).build();
182+
builder.setDefaultRequestConfig(defaultConfig);
183+
184+
initConnectionManager();
185+
builder.setConnectionManager(connectionManager);
186+
ApacheIdleConnectionCleaner.registerConnectionManager(connectionManager, config.getMaxIdleTimeMillis());
187+
188+
initExecutor();
154189

155190
// keepAlive
156191
if (config.getKeepAliveDurationMillis() > 0) {
@@ -169,6 +204,7 @@ public long getKeepAliveDuration(org.apache.http.HttpResponse response, HttpCont
169204
}
170205

171206
httpClient = builder.build();
207+
latch.countDown();
172208
}
173209

174210
private HttpUriRequest parseToHttpRequest(HttpRequest apiReq) throws IOException, ClientException {
@@ -324,10 +360,12 @@ public boolean isSingleton() {
324360
@Override
325361
public void close() throws IOException {
326362
client = null;
327-
executorService.shutdown();
328-
ApacheIdleConnectionCleaner.removeConnectionManager(connectionManager);
329-
connectionManager.shutdown();
330-
IOUtils.closeQuietly(httpClient);
363+
if (initialized.compareAndSet(true, false)) {
364+
executorService.shutdown();
365+
ApacheIdleConnectionCleaner.removeConnectionManager(connectionManager);
366+
connectionManager.shutdown();
367+
IOUtils.closeQuietly(httpClient);
368+
}
331369
}
332370

333371
private class DefaultAsyncThreadFactory implements ThreadFactory {

0 commit comments

Comments
 (0)