
com.taotao.cloud.openfeign.configuration.OkHttpAutoConfiguration Maven / Gradle / Ivy
Show all versions of taotao-cloud-starter-openfeign Show documentation
/*
* Copyright (c) 2020-2030, Shuigedeng ([email protected] & https://blog.taotaocloud.top/).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.taotao.cloud.openfeign.configuration;
import com.taotao.cloud.common.constant.StarterName;
import com.taotao.cloud.common.utils.log.LogUtils;
import com.taotao.cloud.openfeign.annotation.ConditionalOnFeignUseOkHttp;
import jakarta.annotation.PreDestroy;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.openfeign.loadbalancer.FeignLoadBalancerAutoConfiguration;
import org.springframework.cloud.openfeign.support.FeignHttpClientProperties;
import org.springframework.context.annotation.Bean;
/**
* OkHttp 自动配置
*
* 1. 默认让 Feign 使用 OkHttp 作为 HttpClient。所以直接使用 Feign 的配置来对 OkHttp 进行配置。 2. 如果存在
* `feign.okhttp.enabled` 配置, 同时其值为 `true`,就会自动配置 OkHttp。 3. 在此处配置 OkHttp,也是为了共用 OkHttp 的配置,让其可以同时支持
* RestTemplate
*
*
{@code org.springframework.cloud.openfeign.loadbalancer.OkHttpFeignLoadBalancerConfiguration}
*
* @author shuigedeng
* @version 2022.07
* @since 2022-07-02 09:31:33
*/
@AutoConfiguration(before = FeignLoadBalancerAutoConfiguration.class)
@ConditionalOnFeignUseOkHttp
public class OkHttpAutoConfiguration implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
LogUtils.started(OkHttpAutoConfiguration.class, StarterName.OPENFEIGN_STARTER);
}
private OkHttpClient okHttpClient;
@Bean
@ConditionalOnMissingBean
public okhttp3.OkHttpClient.Builder okHttpClientBuilder() {
return new okhttp3.OkHttpClient.Builder();
}
@Bean
@ConditionalOnMissingBean(ConnectionPool.class)
public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties) {
int maxTotalConnections = httpClientProperties.getMaxConnections();
long timeToLive = httpClientProperties.getTimeToLive();
TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
return new ConnectionPool(maxTotalConnections, timeToLive, ttlUnit);
}
@Bean
public okhttp3.OkHttpClient okHttpClient(
okhttp3.OkHttpClient.Builder builder,
ConnectionPool connectionPool,
FeignHttpClientProperties httpClientProperties) {
boolean followRedirects = httpClientProperties.isFollowRedirects();
int connectTimeout = httpClientProperties.getConnectionTimeout();
boolean disableSslValidation = httpClientProperties.isDisableSslValidation();
Duration readTimeout = httpClientProperties.getOkHttp().getReadTimeout();
if (disableSslValidation) {
disableSsl(builder);
}
this.okHttpClient = builder.connectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
.followRedirects(followRedirects)
.readTimeout(readTimeout)
.connectionPool(connectionPool)
.build();
return this.okHttpClient;
}
private void disableSsl(okhttp3.OkHttpClient.Builder builder) {
try {
X509TrustManager disabledTrustManager = new OkHttpAutoConfiguration.DisableValidationTrustManager();
TrustManager[] trustManagers = new TrustManager[1];
trustManagers[0] = disabledTrustManager;
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, new java.security.SecureRandom());
SSLSocketFactory disabledSSLSocketFactory = sslContext.getSocketFactory();
builder.sslSocketFactory(disabledSSLSocketFactory, disabledTrustManager);
builder.hostnameVerifier(new OkHttpAutoConfiguration.TrustAllHostnames());
} catch (NoSuchAlgorithmException | KeyManagementException e) {
LogUtils.warn("Error setting SSLSocketFactory in OKHttpClient", e);
}
}
@PreDestroy
public void destroy() {
if (this.okHttpClient != null) {
this.okHttpClient.dispatcher().executorService().shutdown();
this.okHttpClient.connectionPool().evictAll();
}
}
@Bean
@ConditionalOnMissingBean(OkHttpClient.class)
public OkHttpClient feignClient(okhttp3.OkHttpClient.Builder client) {
return new OkHttpClient(client);
}
/** A {@link X509TrustManager} that does not validate SSL certificates. */
class DisableValidationTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
class TrustAllHostnames implements HostnameVerifier {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}
}