11package me .chanjar .weixin .common .util .http ;
22
3- import java .io .IOException ;
4- import java .util .concurrent .TimeUnit ;
5-
3+ import me .chanjar .weixin .common .util .StringUtils ;
64import org .apache .http .annotation .NotThreadSafe ;
75import org .apache .http .auth .AuthScope ;
86import org .apache .http .auth .UsernamePasswordCredentials ;
2220import org .apache .http .impl .client .HttpClients ;
2321import org .apache .http .impl .conn .PoolingHttpClientConnectionManager ;
2422import org .apache .http .protocol .HttpContext ;
23+ import org .slf4j .Logger ;
24+ import org .slf4j .LoggerFactory ;
2525
26- import me .chanjar .weixin .common .util .StringUtils ;
26+ import java .io .IOException ;
27+ import java .util .concurrent .TimeUnit ;
28+ import java .util .concurrent .atomic .AtomicBoolean ;
2729
2830/**
2931 * httpclient 连接管理器
32+ *
3033 * @author kakotor
3134 */
3235@ NotThreadSafe
3336public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder {
37+ protected final Logger log = LoggerFactory .getLogger (DefaultApacheHttpClientBuilder .class );
38+ private final AtomicBoolean prepared = new AtomicBoolean (false );
3439 private int connectionRequestTimeout = 3000 ;
3540 private int connectionTimeout = 5000 ;
3641 private int soTimeout = 5000 ;
@@ -47,21 +52,17 @@ public boolean retryRequest(IOException exception, int executionCount, HttpConte
4752 };
4853 private SSLConnectionSocketFactory sslConnectionSocketFactory = SSLConnectionSocketFactory .getSocketFactory ();
4954 private PlainConnectionSocketFactory plainConnectionSocketFactory = PlainConnectionSocketFactory .getSocketFactory ();
50-
5155 private String httpProxyHost ;
5256 private int httpProxyPort ;
5357 private String httpProxyUsername ;
5458 private String httpProxyPassword ;
55-
5659 /**
5760 * 闲置连接监控线程
5861 */
5962 private IdleConnectionMonitorThread idleConnectionMonitorThread ;
60-
6163 private HttpClientBuilder httpClientBuilder ;
6264
6365 private DefaultApacheHttpClientBuilder () {
64- prepare ();
6566 }
6667
6768 public static DefaultApacheHttpClientBuilder get () {
@@ -98,11 +99,98 @@ public ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFac
9899 return this ;
99100 }
100101
102+ /**
103+ * 获取链接的超时时间设置,默认3000ms
104+ * <p>
105+ * 设置为零时不超时,一直等待.
106+ * 设置为负数是使用系统默认设置(非上述的3000ms的默认值,而是httpclient的默认设置).
107+ * </p>
108+ *
109+ * @param connectionRequestTimeout 获取链接的超时时间设置(单位毫秒),默认3000ms
110+ */
111+ public void setConnectionRequestTimeout (int connectionRequestTimeout ) {
112+ this .connectionRequestTimeout = connectionRequestTimeout ;
113+ }
114+
115+ /**
116+ * 建立链接的超时时间,默认为5000ms.由于是在链接池获取链接,此设置应该并不起什么作用
117+ * <p>
118+ * 设置为零时不超时,一直等待.
119+ * 设置为负数是使用系统默认设置(非上述的5000ms的默认值,而是httpclient的默认设置).
120+ * </p>
121+ *
122+ * @param connectionTimeout 建立链接的超时时间设置(单位毫秒),默认5000ms
123+ */
124+ public void setConnectionTimeout (int connectionTimeout ) {
125+ this .connectionTimeout = connectionTimeout ;
126+ }
127+
128+ /**
129+ * 默认NIO的socket超时设置,默认5000ms.
130+ *
131+ * @param soTimeout 默认NIO的socket超时设置,默认5000ms.
132+ * @see java.net.SocketOptions#SO_TIMEOUT
133+ */
134+ public void setSoTimeout (int soTimeout ) {
135+ this .soTimeout = soTimeout ;
136+ }
137+
138+ /**
139+ * 空闲链接的超时时间,默认60000ms.
140+ * <p>
141+ * 超时的链接将在下一次空闲链接检查是被销毁
142+ * </p>
143+ *
144+ * @param idleConnTimeout 空闲链接的超时时间,默认60000ms.
145+ */
146+ public void setIdleConnTimeout (int idleConnTimeout ) {
147+ this .idleConnTimeout = idleConnTimeout ;
148+ }
149+
150+ /**
151+ * 检查空间链接的间隔周期,默认60000ms.
152+ *
153+ * @param checkWaitTime 检查空间链接的间隔周期,默认60000ms.
154+ */
155+ public void setCheckWaitTime (int checkWaitTime ) {
156+ this .checkWaitTime = checkWaitTime ;
157+ }
158+
159+ /**
160+ * 每路的最大链接数,默认10
161+ *
162+ * @param maxConnPerHost 每路的最大链接数,默认10
163+ */
164+ public void setMaxConnPerHost (int maxConnPerHost ) {
165+ this .maxConnPerHost = maxConnPerHost ;
166+ }
167+
168+ /**
169+ * 最大总连接数,默认50
170+ *
171+ * @param maxTotalConn 最大总连接数,默认50
172+ */
173+ public void setMaxTotalConn (int maxTotalConn ) {
174+ this .maxTotalConn = maxTotalConn ;
175+ }
176+
177+ /**
178+ * 自定义httpclient的User Agent
179+ *
180+ * @param userAgent User Agent
181+ */
182+ public void setUserAgent (String userAgent ) {
183+ this .userAgent = userAgent ;
184+ }
185+
101186 public IdleConnectionMonitorThread getIdleConnectionMonitorThread () {
102187 return this .idleConnectionMonitorThread ;
103188 }
104189
105- private void prepare () {
190+ private synchronized void prepare () {
191+ if (prepared .get ()){
192+ return ;
193+ }
106194 Registry <ConnectionSocketFactory > registry = RegistryBuilder .<ConnectionSocketFactory >create ()
107195 .register ("http" , this .plainConnectionSocketFactory )
108196 .register ("https" , this .sslConnectionSocketFactory )
@@ -149,11 +237,14 @@ private void prepare() {
149237 if (StringUtils .isNotBlank (this .userAgent )) {
150238 this .httpClientBuilder .setUserAgent (this .userAgent );
151239 }
152-
240+ prepared . set ( true );
153241 }
154242
155243 @ Override
156244 public CloseableHttpClient build () {
245+ if (!prepared .get ()){
246+ prepare ();
247+ }
157248 return this .httpClientBuilder .build ();
158249 }
159250
0 commit comments