/**
* - Supports both HTTP and HTTPS
* - Uses a connection pool to re-use connections and save overhead of creating connections.
* - Has a custom connection keep-alive strategy (to apply a default keep-alive if one isn't specified)
* - Starts an idle connection monitor to continuously clean up stale connections.
*
* @author XiongNeng
* @version 1.0
* @since 2018/7/5
*/@Configuration@EnableSchedulingpublicclassHttpClientConfig{privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(HttpClientConfig.class);@ResourceprivateHttpClientPropertiesp;@BeanpublicPoolingHttpClientConnectionManagerpoolingConnectionManager(){SSLContextBuilderbuilder=newSSLContextBuilder();try{builder.loadTrustMaterial(null,newTrustStrategy(){publicbooleanisTrusted(X509Certificate[]arg0,Stringarg1){returntrue;}});}catch(NoSuchAlgorithmException|KeyStoreExceptione){LOGGER.error("Pooling Connection Manager Initialisation failure because of "+e.getMessage(),e);}SSLConnectionSocketFactorysslsf=null;try{sslsf=newSSLConnectionSocketFactory(builder.build());}catch(KeyManagementException|NoSuchAlgorithmExceptione){LOGGER.error("Pooling Connection Manager Initialisation failure because of "+e.getMessage(),e);}Registry<ConnectionSocketFactory>socketFactoryRegistry=RegistryBuilder.<ConnectionSocketFactory>create().register("https",sslsf).register("http",newPlainConnectionSocketFactory()).build();PoolingHttpClientConnectionManagerpoolingConnectionManager=newPoolingHttpClientConnectionManager(socketFactoryRegistry);poolingConnectionManager.setMaxTotal(p.getMaxTotalConnections());//最大连接数poolingConnectionManager.setDefaultMaxPerRoute(p.getDefaultMaxPerRoute());//同路由并发数returnpoolingConnectionManager;}@BeanpublicConnectionKeepAliveStrategyconnectionKeepAliveStrategy(){returnnewConnectionKeepAliveStrategy(){@OverridepubliclonggetKeepAliveDuration(HttpResponseresponse,HttpContexthttpContext){HeaderElementIteratorit=newBasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));while(it.hasNext()){HeaderElementhe=it.nextElement();Stringparam=he.getName();Stringvalue=he.getValue();if(value!=null&¶m.equalsIgnoreCase("timeout")){returnLong.parseLong(value)*1000;}}returnp.getDefaultKeepAliveTimeMillis();}};}@BeanpublicCloseableHttpClienthttpClient(){RequestConfigrequestConfig=RequestConfig.custom().setConnectionRequestTimeout(p.getRequestTimeout()).setConnectTimeout(p.getConnectTimeout()).setSocketTimeout(p.getSocketTimeout()).build();returnHttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(poolingConnectionManager()).setKeepAliveStrategy(connectionKeepAliveStrategy()).setRetryHandler(newDefaultHttpRequestRetryHandler(3,true))// 重试次数.build();}@BeanpublicRunnableidleConnectionMonitor(finalPoolingHttpClientConnectionManagerconnectionManager){returnnewRunnable(){@Override@Scheduled(fixedDelay=10000)publicvoidrun(){try{if(connectionManager!=null){LOGGER.trace("run IdleConnectionMonitor - Closing expired and idle connections...");connectionManager.closeExpiredConnections();connectionManager.closeIdleConnections(p.getCloseIdleConnectionWaitTimeSecs(),TimeUnit.SECONDS);}else{LOGGER.trace("run IdleConnectionMonitor - Http Client Connection manager is not initialised");}}catch(Exceptione){LOGGER.error("run IdleConnectionMonitor - Exception occurred. msg={}, e={}",e.getMessage(),e);}}};}@BeanpublicTaskSchedulertaskScheduler(){ThreadPoolTaskSchedulerscheduler=newThreadPoolTaskScheduler();scheduler.setThreadNamePrefix("poolScheduler");scheduler.setPoolSize(50);returnscheduler;}}