3737import java .util .List ;
3838import java .util .Map ;
3939import java .util .concurrent .*;
40+ import java .util .concurrent .atomic .AtomicBoolean ;
4041import java .util .concurrent .atomic .AtomicInteger ;
4142
4243public 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