diff --git a/README.md b/README.md
index caf3724..7d57fca 100644
--- a/README.md
+++ b/README.md
@@ -29,15 +29,13 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter]
## 功能特性
-- [x] [超时时间设置](#超时时间设置)
+- [x] [自定义OkHttpClient属性](#自定义OkHttpClient属性)
- [x] [注解式拦截器](#注解式拦截器)
- [x] [日志打印](#日志打印)
- [x] [请求重试](#请求重试)
- [x] [熔断降级](#熔断降级)
- [x] [错误解码器](#错误解码器)
-- [x] [自定义注入OkHttpClient](#自定义注入OkHttpClient)
- [x] [微服务之间的HTTP调用](#微服务之间的HTTP调用)
-- [x] [连接池管理](#连接池管理)
- [x] [全局拦截器](#全局拦截器)
- [x] [调用适配器](#调用适配器)
- [x] [数据转换器](#数据转码器)
@@ -52,7 +50,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter]
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.3.2
+ 2.3.3
```
@@ -65,7 +63,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter]
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.3.2
+ 2.3.3
com.squareup.okhttp3
@@ -151,15 +149,6 @@ public class TestService {
```yaml
retrofit:
- # 连接池配置
- pool:
- # default连接池
- default:
- # 最大空闲连接数
- max-idle-connections: 5
- # 连接保活时间(秒)
- keep-alive-second: 300
-
# 全局转换器工厂
global-converter-factories:
- com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory
@@ -178,7 +167,7 @@ retrofit:
# 全局日志打印策略
log-strategy: basic
- # 重试配置
+ # 全局重试配置
global-retry:
# 是否启用全局重试
enable: false
@@ -227,53 +216,39 @@ retrofit:
# 指定断路器应保持半开多长时间的等待持续时间,可选配置,大于1才是有效配置。
max-wait-duration-in-half-open-state-seconds: 0
# 忽略的异常类列表,只有配置值之后才会加载。
- ignore-exceptions: []
+ ignore-exceptions: [ ]
# 记录的异常类列表,只有配置值之后才会加载。
- record-exceptions: []
+ record-exceptions: [ ]
# 慢调用比例阈值
slow-call-rate-threshold: 100
# 慢调用阈值秒数,超过该秒数视为慢调用
slow-call-duration-threshold-seconds: 60
# 启用可写堆栈跟踪的标志
writable-stack-trace-enabled: true
-
- # 全局连接超时时间
- global-connect-timeout-ms: 10000
- # 全局读取超时时间
- global-read-timeout-ms: 10000
- # 全局写入超时时间
- global-write-timeout-ms: 10000
- # 全局完整调用超时时间
- global-call-timeout-ms: 0
-
```
## 高级功能
-### 超时时间设置
-
-`retrofit-spring-boot-starter`支持两种方式设置超时时间,一种是全局超时时间设置,另一种是注解超时时间设置。
+### 自定义OkHttpClient属性
-#### 全局超时时间设置
+根据`@RetrofitClient`的`baseOkHttpClientBeanName`,根据该名称从Spring容器中对应的`OkHttpClient`来初始化当前接口的`OkHttpClient`。
+通过这种方式,用户可以配置超时时间、代理、连接池、分发等等`OkHttpClient`属性。
-**在yaml文件中可配置全局超时时间,对所有接口生效**。
+默认是`defaultBaseOkHttpClient`,可以按下面方式覆盖Spring配置:
-```yaml
-retrofit:
- # 全局连接超时时间
- global-connect-timeout-ms: 5000
- # 全局读取超时时间
- global-read-timeout-ms: 5000
- # 全局写入超时时间
- global-write-timeout-ms: 5000
- # 全局完整调用超时时间
- global-call-timeout-ms: 0
+```java
+@Bean
+@Primary
+OkHttpClient defaultBaseOkHttpClient(){
+ return new OkHttpClient.Builder()
+ .addInterceptor(chain->{
+ log.info("=======替换defaultBaseOkHttpClient=====");
+ return chain.proceed(chain.request());
+ })
+ .build();
+ }
```
-#### 注解式超时时间设置
-
-在`@RetrofitClient`注解上可以设置超时时间,针对当前接口生效,优先级更高。具体字段有`connectTimeoutMs`、`readTimeoutMs`、`writeTimeoutMs`、`callTimeoutMs`等。
-
### 注解式拦截器
很多时候,我们希望某个接口下的某些http请求执行统一的拦截处理逻辑。为了支持这个功能,`retrofit-spring-boot-starter`提供了**注解式拦截器**,做到了**基于url路径的匹配拦截**。使用的步骤主要分为2步:
@@ -696,32 +671,6 @@ public interface ErrorDecoder {
```
-### 自定义注入OkHttpClient
-
-通常情况下,通过`@RetrofitClient`注解属性动态创建`OkHttpClient`对象能够满足大部分使用场景。但是在某些情况下,用户可能需要自定义`OkHttpClient`
-,这个时候,可以在接口上定义返回类型是`OkHttpClient.Builder`的静态方法来实现。代码示例如下:
-
-```java
-
-@RetrofitClient(baseUrl = "http://ke.com")
-public interface HttpApi3 {
-
- @OkHttpClientBuilder
- static OkHttpClient.Builder okhttpClientBuilder() {
- return new OkHttpClient.Builder()
- .connectTimeout(1, TimeUnit.SECONDS)
- .readTimeout(1, TimeUnit.SECONDS)
- .writeTimeout(1, TimeUnit.SECONDS);
-
- }
-
- @GET
- Result getPerson(@Url String url, @Query("id") Long id);
-}
-```
-
-> 方法必须使用`@OkHttpClientBuilder`注解标记!
-
### 微服务之间的HTTP调用
为了能够使用微服务调用,需要进行如下配置:
@@ -749,36 +698,6 @@ public interface ApiCountService {
}
```
-### 连接池管理
-
-默认情况下,所有通过`Retrofit`发送的http请求都会使用`max-idle-connections=5 keep-alive-second=300`
-的默认连接池。当然,我们也可以在配置文件中配置多个自定义的连接池,然后通过`@RetrofitClient`的`poolName`属性来指定使用。比如我们要让某个接口下的请求全部使用`poolName=test1`的连接池,代码实现如下:
-
-1. 配置连接池。
-
- ```yaml
- retrofit:
- # 连接池配置
- pool:
- # test1连接池配置
- test1:
- # 最大空闲连接数
- max-idle-connections: 3
- # 连接保活时间(秒)
- keep-alive-second: 100
- ```
-
-2. 通过`@RetrofitClient`的`poolName`属性来指定使用的连接池。
-
- ```java
- @RetrofitClient(baseUrl = "${test.baseUrl}", poolName="test1")
- public interface HttpApi {
-
- @GET("person")
- Result getPerson(@Query("id") Long id);
- }
- ```
-
## 全局拦截器
### 全局应用拦截器
diff --git a/pom.xml b/pom.xml
index d440821..0307e88 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.github.lianjiatech
retrofit-spring-boot-starter
- 2.3.2
+ 2.3.3
retrofit-spring-boot-starter
retrofit-spring-boot-starter
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/PoolConfig.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/PoolConfig.java
deleted file mode 100644
index 4786049..0000000
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/PoolConfig.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.github.lianjiatech.retrofit.spring.boot.config;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * @author 陈添明
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class PoolConfig {
-
- private int maxIdleConnections;
-
- private long keepAliveSecond;
-}
\ No newline at end of file
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java
index 8bcf097..ca0e11c 100644
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java
+++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java
@@ -1,9 +1,6 @@
package com.github.lianjiatech.retrofit.spring.boot.config;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -13,6 +10,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.Primary;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
@@ -20,6 +18,7 @@
import com.github.lianjiatech.retrofit.spring.boot.core.AutoConfiguredRetrofitScannerRegistrar;
import com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory;
import com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory;
+import com.github.lianjiatech.retrofit.spring.boot.core.Constants;
import com.github.lianjiatech.retrofit.spring.boot.core.ErrorDecoder;
import com.github.lianjiatech.retrofit.spring.boot.core.PathMatchInterceptorBdfProcessor;
import com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory;
@@ -36,7 +35,7 @@
import com.github.lianjiatech.retrofit.spring.boot.retry.RetryInterceptor;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
-import okhttp3.ConnectionPool;
+import okhttp3.OkHttpClient;
import retrofit2.converter.jackson.JacksonConverterFactory;
/**
@@ -77,16 +76,6 @@ public RetrofitConfigBean retrofitConfigBean(@Autowired(required = false) Retrof
retrofitConfigBean.setRetryInterceptor(retryInterceptor);
retrofitConfigBean.setLoggingInterceptor(loggingInterceptor);
retrofitConfigBean.setErrorDecoderInterceptor(errorDecoderInterceptor);
-
- Map poolRegistry = new HashMap<>(4);
- retrofitProperties.getPool().forEach((poolName, poolConfig) -> {
- long keepAliveSecond = poolConfig.getKeepAliveSecond();
- int maxIdleConnections = poolConfig.getMaxIdleConnections();
- ConnectionPool connectionPool =
- new ConnectionPool(maxIdleConnections, keepAliveSecond, TimeUnit.SECONDS);
- poolRegistry.put(poolName, connectionPool);
- });
- retrofitConfigBean.setPoolRegistry(poolRegistry);
retrofitConfigBean.setGlobalCallAdapterFactoryClasses(retrofitProperties.getGlobalCallAdapterFactories());
retrofitConfigBean.setGlobalConverterFactoryClasses(retrofitProperties.getGlobalConverterFactories());
return retrofitConfigBean;
@@ -126,7 +115,7 @@ public RetryInterceptor retryInterceptor() {
@Bean
@ConditionalOnMissingBean
- public LoggingInterceptor logInterceptor() {
+ public LoggingInterceptor loggingInterceptor() {
return new LoggingInterceptor(retrofitProperties.getGlobalLog());
}
@@ -142,18 +131,26 @@ ServiceChooseInterceptor serviceChooseInterceptor(@Autowired ServiceInstanceChoo
return new ServiceChooseInterceptor(serviceInstanceChooser);
}
+ @Bean
+ @Primary
+ @ConditionalOnMissingBean(name = Constants.DEFAULT_BASE_OK_HTTP_CLIENT)
+ OkHttpClient defaultBaseOkHttpClient() {
+ return new OkHttpClient.Builder()
+ .build();
+ }
+
@Bean
@ConditionalOnMissingBean
- @ConditionalOnClass(name = "com.alibaba.csp.sentinel.SphU")
- @ConditionalOnProperty(name = "retrofit.degrade.degrade-type", havingValue = RetrofitDegrade.SENTINEL)
+ @ConditionalOnClass(name = Constants.SPH_U_CLASS_NAME)
+ @ConditionalOnProperty(name = Constants.DEGRADE_TYPE, havingValue = RetrofitDegrade.SENTINEL)
public RetrofitDegrade sentinelRetrofitDegrade() {
return new SentinelRetrofitDegrade(retrofitProperties.getDegrade().getGlobalSentinelDegrade());
}
@Bean
@ConditionalOnMissingBean
- @ConditionalOnClass(name = "io.github.resilience4j.circuitbreaker.CircuitBreaker")
- @ConditionalOnProperty(name = "retrofit.degrade.degrade-type", havingValue = RetrofitDegrade.RESILIENCE4J)
+ @ConditionalOnClass(name = Constants.CIRCUIT_BREAKER_CLASS_NAME)
+ @ConditionalOnProperty(name = Constants.DEGRADE_TYPE, havingValue = RetrofitDegrade.RESILIENCE4J)
public RetrofitDegrade resilience4jRetrofitDegrade() {
return new Resilience4jRetrofitDegrade(CircuitBreakerRegistry.ofDefaults(),
retrofitProperties.getDegrade().getGlobalResilience4jDegrade());
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitConfigBean.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitConfigBean.java
index 24fa53f..1858fc1 100644
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitConfigBean.java
+++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitConfigBean.java
@@ -2,7 +2,6 @@
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import com.github.lianjiatech.retrofit.spring.boot.degrade.RetrofitDegrade;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.ErrorDecoderInterceptor;
@@ -13,7 +12,6 @@
import com.github.lianjiatech.retrofit.spring.boot.retry.RetryInterceptor;
import lombok.Data;
-import okhttp3.ConnectionPool;
import retrofit2.CallAdapter;
import retrofit2.Converter;
@@ -25,8 +23,6 @@ public class RetrofitConfigBean {
private final RetrofitProperties retrofitProperties;
- private Map poolRegistry;
-
private List globalInterceptors;
private List networkInterceptors;
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java
index 4fdabec..3cc1ca7 100644
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java
+++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java
@@ -1,13 +1,11 @@
package com.github.lianjiatech.retrofit.spring.boot.config;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory;
import com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory;
+import com.github.lianjiatech.retrofit.spring.boot.core.Constants;
import com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory;
import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeProperty;
import com.github.lianjiatech.retrofit.spring.boot.log.GlobalLogProperty;
@@ -21,19 +19,10 @@
/**
* @author 陈添明
*/
-@ConfigurationProperties(prefix = "retrofit")
+@ConfigurationProperties(prefix = Constants.RETROFIT)
@Data
public class RetrofitProperties {
- private static final String DEFAULT_POOL = "default";
-
- /**
- * 连接池配置
- * Connection pool configuration
- */
- @NestedConfigurationProperty
- private Map pool = new LinkedHashMap<>();
-
/**
* 全局重试配置
* retry config
@@ -55,26 +44,6 @@ public class RetrofitProperties {
@NestedConfigurationProperty
private GlobalLogProperty globalLog = new GlobalLogProperty();
- /**
- * 全局连接超时时间
- */
- private int globalConnectTimeoutMs = 10_000;
-
- /**
- * 全局读取超时时间
- */
- private int globalReadTimeoutMs = 10_000;
-
- /**
- * 全局写入超时时间
- */
- private int globalWriteTimeoutMs = 10_000;
-
- /**
- * 全局完整调用超时时间
- */
- private int globalCallTimeoutMs = 0;
-
/**
* 全局转换器工厂,转换器实例优先从Spring容器获取,如果没有获取到,则反射创建。
* global converter factories, The converter instance is first obtained from the Spring container. If it is not obtained, it is created by reflection.
@@ -91,12 +60,4 @@ public class RetrofitProperties {
private Class extends CallAdapter.Factory>[] globalCallAdapterFactories =
(Class extends CallAdapter.Factory>[])new Class[] {BodyCallAdapterFactory.class,
ResponseCallAdapterFactory.class};
-
- public Map getPool() {
- if (!pool.isEmpty()) {
- return pool;
- }
- pool.put(DEFAULT_POOL, new PoolConfig(5, 300));
- return pool;
- }
}
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/Constants.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/Constants.java
new file mode 100644
index 0000000..17891a7
--- /dev/null
+++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/Constants.java
@@ -0,0 +1,20 @@
+package com.github.lianjiatech.retrofit.spring.boot.core;
+
+/**
+ * @author 陈添明
+ * @since 2022/5/24 1:31 下午
+ */
+public interface Constants {
+
+ String STR_EMPTY = "";
+
+ String DEFAULT_BASE_OK_HTTP_CLIENT = "defaultBaseOkHttpClient";
+
+ String SPH_U_CLASS_NAME = "com.alibaba.csp.sentinel.SphU";
+
+ String DEGRADE_TYPE = "retrofit.degrade.degrade-type";
+
+ String CIRCUIT_BREAKER_CLASS_NAME = "io.github.resilience4j.circuitbreaker.CircuitBreaker";
+
+ String RETROFIT = "retrofit";
+}
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClient.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClient.java
index 2614fbf..41075ce 100644
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClient.java
+++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClient.java
@@ -29,21 +29,19 @@
* Can be specified as property key, eg: ${propertyKey}.
* If baseUrl is not configured, you must configure serviceId and path optional configuration.
*
- *
- * @return baseUrl
*/
- String baseUrl() default "";
+ String baseUrl() default Constants.STR_EMPTY;
/**
* The name of the service.
* Can be specified as property key, eg: ${propertyKey}.
*/
- String serviceId() default "";
+ String serviceId() default Constants.STR_EMPTY;
/**
* Path prefix to be used by all method-level mappings.
*/
- String path() default "";
+ String path() default Constants.STR_EMPTY;
/**
* 适用于当前接口的转换器工厂,优先级比全局转换器工厂更高。转换器实例优先从Spring容器获取,如果没有获取到,则反射创建。
@@ -80,17 +78,9 @@
* The invalid response is determined by the business itself.
* In general, the invalid response corresponding to each service is different, you can customize the corresponding {@link ErrorDecoder}, and then configure it here.
*
- * @return ErrorDecoder
*/
Class extends ErrorDecoder> errorDecoder() default ErrorDecoder.DefaultErrorDecoder.class;
- /**
- * connection pool name
- *
- * @return connection pool name
- */
- String poolName() default "default";
-
/**
* When calling {@link Retrofit#create(Class)} on the resulting {@link Retrofit} instance, eagerly validate the
* configuration of all methods in the supplied interface.
@@ -100,70 +90,8 @@
boolean validateEagerly() default false;
/**
- * Sets the default connect timeout for new connections. A value of 0 means no timeout,
- * otherwise values must be between 1 and Integer.MAX_VALUE when converted to milliseconds.
- * If it is configured as -1, the global default configuration is used.
- *
- * @return connectTimeoutMs
- */
- int connectTimeoutMs() default -1;
-
- /**
- * Sets the default read timeout for new connections. A value of 0 means no timeout,
- * otherwise values must be between 1 and Integer.MAX_VALUE when converted to milliseconds.
- * If it is configured as -1, the global default configuration is used.
- *
- * @return readTimeoutMs
- */
- int readTimeoutMs() default -1;
-
- /**
- * Sets the default write timeout for new connections. A value of 0 means no timeout,
- * otherwise values must be between 1 and Integer.MAX_VALUE when converted to milliseconds.
- * If it is configured as -1, the global default configuration is used.
- *
- * @return writeTimeoutMs
- */
- int writeTimeoutMs() default -1;
-
- /**
- * Sets the default timeout for complete calls. A value of 0 means no timeout,
- * otherwise values must be between 1 and Integer.MAX_VALUE when converted to milliseconds.
- *
- * @return callTimeout
- */
- int callTimeoutMs() default -1;
-
- /**
- * Sets the interval between HTTP/2 and web socket pings initiated by this client.
- * Use this to automatically send ping frames until either the connection fails or it is closed.
- * This keeps the connection alive and may detect connectivity failures.
- *
- * @return pingInterval
- */
- int pingIntervalMs() default 0;
-
- /**
- * Configure this client to allow protocol redirects from HTTPS to HTTP and from HTTP to HTTPS.
- * Redirects are still first restricted by followRedirects. Defaults to true.
- *
- * @return followSslRedirects
- */
- boolean followSslRedirects() default true;
-
- /**
- * Configure this client to follow redirects. If unset, redirects will be followed.
- *
- * @return followRedirects
- */
- boolean followRedirects() default true;
-
- /**
- * Configure this client to retry or not when a connectivity problem is encountered.
- * By default, this client silently recovers from the following problems:
- *
- * @return retryOnConnectionFailure
+ * 根据该名称从Spring容器中对应的OkHttpClient来初始化当前接口的OkHttpClient
*/
- boolean retryOnConnectionFailure() default true;
+ String baseOkHttpClientBeanName() default Constants.DEFAULT_BASE_OK_HTTP_CLIENT;
}
diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java
index 5f9c3f8..b659223 100644
--- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java
+++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java
@@ -1,9 +1,6 @@
package com.github.lianjiatech.retrofit.spring.boot.core;
import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -11,7 +8,6 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.concurrent.TimeUnit;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
@@ -25,7 +21,6 @@
import org.springframework.util.StringUtils;
import com.github.lianjiatech.retrofit.spring.boot.config.RetrofitConfigBean;
-import com.github.lianjiatech.retrofit.spring.boot.config.RetrofitProperties;
import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeProxy;
import com.github.lianjiatech.retrofit.spring.boot.degrade.RetrofitDegrade;
import com.github.lianjiatech.retrofit.spring.boot.interceptor.BasePathMatchInterceptor;
@@ -36,7 +31,6 @@
import com.github.lianjiatech.retrofit.spring.boot.util.BeanExtendUtils;
import com.github.lianjiatech.retrofit.spring.boot.util.RetrofitUtils;
-import okhttp3.ConnectionPool;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
@@ -50,8 +44,6 @@ public class RetrofitFactoryBean implements FactoryBean, EnvironmentAware,
private Environment environment;
- private RetrofitProperties retrofitProperties;
-
private RetrofitConfigBean retrofitConfigBean;
private ApplicationContext applicationContext;
@@ -88,22 +80,12 @@ public boolean isSingleton() {
return true;
}
- private okhttp3.ConnectionPool parseConnectionPool() {
- RetrofitClient retrofitClient =
- AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, RetrofitClient.class);
- String poolName = retrofitClient.poolName();
- Map poolRegistry = retrofitConfigBean.getPoolRegistry();
- Assert.notNull(poolRegistry, "poolRegistry does not exist! Please set retrofitConfigBean.poolRegistry!");
- ConnectionPool connectionPool = poolRegistry.get(poolName);
- Assert.notNull(connectionPool,
- "The connection pool corresponding to the current poolName does not exist! poolName = " + poolName);
- return connectionPool;
- }
-
- private OkHttpClient createOkHttpClient() throws IllegalAccessException, InvocationTargetException {
- OkHttpClient.Builder okHttpClientBuilder = createOkHttpClientBuilder();
+ private OkHttpClient createOkHttpClient() {
RetrofitClient retrofitClient =
AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, RetrofitClient.class);
+ OkHttpClient baseOkHttpClient = applicationContext.getBean(
+ Objects.requireNonNull(retrofitClient).baseOkHttpClientBeanName(), OkHttpClient.class);
+ OkHttpClient.Builder okHttpClientBuilder = baseOkHttpClient.newBuilder();
if (isEnableDegrade(retrofitInterface)) {
okHttpClientBuilder.addInterceptor(retrofitConfigBean.getRetrofitDegrade());
}
@@ -119,48 +101,6 @@ private OkHttpClient createOkHttpClient() throws IllegalAccessException, Invocat
return okHttpClientBuilder.build();
}
- private OkHttpClient.Builder createOkHttpClientBuilder() throws InvocationTargetException, IllegalAccessException {
- RetrofitClient retrofitClient =
- AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, RetrofitClient.class);
- Method method = findOkHttpClientBuilderMethod();
- if (method != null) {
- return (OkHttpClient.Builder)method.invoke(null);
- }
- okhttp3.ConnectionPool connectionPool = parseConnectionPool();
- final int connectTimeoutMs = retrofitClient.connectTimeoutMs() == -1
- ? retrofitProperties.getGlobalConnectTimeoutMs() : retrofitClient.connectTimeoutMs();
- final int readTimeoutMs = retrofitClient.readTimeoutMs() == -1 ? retrofitProperties.getGlobalReadTimeoutMs()
- : retrofitClient.readTimeoutMs();
- final int writeTimeoutMs = retrofitClient.writeTimeoutMs() == -1
- ? retrofitProperties.getGlobalWriteTimeoutMs() : retrofitClient.writeTimeoutMs();
- final int callTimeoutMs = retrofitClient.callTimeoutMs() == -1 ? retrofitProperties.getGlobalCallTimeoutMs()
- : retrofitClient.callTimeoutMs();
-
- // Construct an OkHttpClient object
- return new OkHttpClient.Builder()
- .connectTimeout(connectTimeoutMs, TimeUnit.MILLISECONDS)
- .readTimeout(readTimeoutMs, TimeUnit.MILLISECONDS)
- .writeTimeout(writeTimeoutMs, TimeUnit.MILLISECONDS)
- .callTimeout(callTimeoutMs, TimeUnit.MILLISECONDS)
- .retryOnConnectionFailure(retrofitClient.retryOnConnectionFailure())
- .followRedirects(retrofitClient.followRedirects())
- .followSslRedirects(retrofitClient.followSslRedirects())
- .pingInterval(retrofitClient.pingIntervalMs(), TimeUnit.MILLISECONDS)
- .connectionPool(connectionPool);
- }
-
- private Method findOkHttpClientBuilderMethod() {
- Method[] methods = retrofitInterface.getMethods();
- for (Method method : methods) {
- if (Modifier.isStatic(method.getModifiers())
- && method.isAnnotationPresent(OkHttpClientBuilder.class)
- && method.getReturnType().equals(OkHttpClient.Builder.class)) {
- return method;
- }
- }
- return null;
- }
-
@SuppressWarnings("unchecked")
private List findInterceptorByAnnotation() {
Annotation[] classAnnotations = AnnotationUtils.getAnnotations(retrofitInterface);
@@ -209,7 +149,7 @@ private List findInterceptorByAnnotation() {
return interceptors;
}
- private Retrofit createRetrofit() throws IllegalAccessException, InvocationTargetException {
+ private Retrofit createRetrofit() {
RetrofitClient retrofitClient =
AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, RetrofitClient.class);
String baseUrl = RetrofitUtils.convertBaseUrl(retrofitClient, retrofitClient.baseUrl(), environment);
@@ -252,6 +192,5 @@ public void setEnvironment(Environment environment) {
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
this.retrofitConfigBean = applicationContext.getBean(RetrofitConfigBean.class);
- this.retrofitProperties = retrofitConfigBean.getRetrofitProperties();
}
}
diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java
index cedc617..84d3ab1 100644
--- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java
+++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java
@@ -1,8 +1,15 @@
package com.github.lianjiatech.retrofit.spring.boot.test;
+import java.util.concurrent.TimeUnit;
+
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.ConnectionPool;
+import okhttp3.Dispatcher;
+import okhttp3.OkHttpClient;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.jaxb.JaxbConverterFactory;
@@ -10,6 +17,7 @@
* @author 陈添明
*/
@MySpringBootApplication
+@Slf4j
public class RetrofitTestApplication {
public static void main(String[] args) {
@@ -25,4 +33,34 @@ GsonConverterFactory gsonConverterFactory() {
JaxbConverterFactory jaxbConverterFactory() {
return JaxbConverterFactory.create();
}
+
+ @Bean
+ @Primary
+ OkHttpClient defaultBaseOkHttpClient() {
+ return new OkHttpClient.Builder()
+ .addInterceptor(chain -> {
+ log.info("=======替换defaultBaseOkHttpClient构建OkHttpClient=====");
+ return chain.proceed(chain.request());
+ })
+ .build();
+ }
+
+ @Bean
+ OkHttpClient testOkHttpClient() {
+ Dispatcher dispatcher = new Dispatcher();
+ dispatcher.setMaxRequests(100);
+ dispatcher.setMaxRequestsPerHost(10);
+
+ return new OkHttpClient.Builder()
+ .readTimeout(1, TimeUnit.SECONDS)
+ .writeTimeout(1, TimeUnit.SECONDS)
+ .connectTimeout(1, TimeUnit.SECONDS)
+ .dispatcher(dispatcher)
+ .connectionPool(new ConnectionPool(10, 10, TimeUnit.MINUTES))
+ .addInterceptor(chain -> {
+ log.info("=======基于testOkHttpClient构建OkHttpClient=====");
+ return chain.proceed(chain.request());
+ })
+ .build();
+ }
}
diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/custom/okhttp/CustomOkHttpTest.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/custom/okhttp/CustomOkHttpTest.java
new file mode 100644
index 0000000..01d2fdb
--- /dev/null
+++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/custom/okhttp/CustomOkHttpTest.java
@@ -0,0 +1,78 @@
+package com.github.lianjiatech.retrofit.spring.boot.test.custom.okhttp;
+
+import java.io.IOException;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.github.lianjiatech.retrofit.spring.boot.test.RetrofitTestApplication;
+import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person;
+import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+
+/**
+ * @author 陈添明
+ */
+@SpringBootTest(classes = RetrofitTestApplication.class)
+@RunWith(SpringRunner.class)
+public class CustomOkHttpTest {
+
+ @Autowired
+ private CustomOkHttpTestApi customOkHttpTestApi;
+
+ private MockWebServer server;
+
+ private static Gson gson = new GsonBuilder()
+ .create();
+
+ @Before
+ public void before() throws IOException {
+ System.out.println("=========开启MockWebServer===========");
+ server = new MockWebServer();
+ server.start(8080);
+
+ }
+
+ @After
+ public void after() throws IOException {
+ System.out.println("=========关闭MockWebServer===========");
+ server.close();
+ }
+
+ @Test
+ public void test() {
+
+ // mock
+ Person mockPerson = new Person().setId(1L)
+ .setName("test")
+ .setAge(10);
+ Result mockResult = new Result<>()
+ .setCode(0)
+ .setMsg("ok")
+ .setData(mockPerson);
+ MockResponse response = new MockResponse()
+ .setResponseCode(200)
+ .addHeader("Content-Type", "application/json; charset=utf-8")
+ .addHeader("Cache-Control", "no-cache")
+ .setBody(gson.toJson(mockResult));
+ server.enqueue(response);
+
+ // http check
+ Result person = customOkHttpTestApi.getPerson(1L);
+ Person data = person.getData();
+ Assert.assertNotNull(data);
+ Assert.assertEquals("test", data.getName());
+ Assert.assertEquals(10, data.getAge().intValue());
+ }
+
+}
diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/custom/okhttp/CustomOkHttpTestApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/custom/okhttp/CustomOkHttpTestApi.java
new file mode 100644
index 0000000..7b219aa
--- /dev/null
+++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/custom/okhttp/CustomOkHttpTestApi.java
@@ -0,0 +1,23 @@
+package com.github.lianjiatech.retrofit.spring.boot.test.custom.okhttp;
+
+import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient;
+import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person;
+import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result;
+
+import retrofit2.http.GET;
+import retrofit2.http.Headers;
+import retrofit2.http.Query;
+
+/**
+ * @author 陈添明
+ */
+@RetrofitClient(baseUrl = "${test.baseUrl}", baseOkHttpClientBeanName = "testOkHttpClient")
+public interface CustomOkHttpTestApi {
+
+ @GET("person")
+ @Headers({
+ "X-Foo: Bar",
+ "X-Ping: Pong"
+ })
+ Result getPerson(@Query("id") Long id);
+}
diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi.java
index cdf9db3..0a8940a 100644
--- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi.java
+++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi.java
@@ -22,7 +22,7 @@
/**
* @author 陈添明
*/
-@RetrofitClient(baseUrl = "${test.baseUrl}", poolName = "test1", errorDecoder = TestErrorDecoder.class)
+@RetrofitClient(baseUrl = "${test.baseUrl}", errorDecoder = TestErrorDecoder.class)
@Sign(accessKeyId = "${test.accessKeyId}", accessKeySecret = "${test.accessKeySecret}", exclude = {"/api/test/query"})
@Intercept(handler = TimeStampInterceptor.class)
@Intercept(handler = TimeStamp2Interceptor.class)
diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml
index 4627471..1afddf7 100644
--- a/src/test/resources/application.yml
+++ b/src/test/resources/application.yml
@@ -1,14 +1,5 @@
retrofit:
- # 连接池配置
- pool:
- # test1连接池配置
- test1:
- # 最大空闲连接数
- max-idle-connections: 3
- # 连接保活时间(秒)
- keep-alive-second: 100
-
# 全局转换器工厂
global-converter-factories:
- com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory
@@ -87,15 +78,6 @@ retrofit:
# 启用可写堆栈跟踪的标志
writable-stack-trace-enabled: true
- # 全局连接超时时间
- global-connect-timeout-ms: 5000
- # 全局读取超时时间
- global-read-timeout-ms: 5000
- # 全局写入超时时间
- global-write-timeout-ms: 5000
- # 全局完整调用超时时间
- global-call-timeout-ms: 0
-
test:
baseUrl: http://localhost:8080/api/test/
accessKeyId: root
diff --git a/src/test/resources/default-config.yml b/src/test/resources/default-config.yml
index 776c32d..f4e67e7 100644
--- a/src/test/resources/default-config.yml
+++ b/src/test/resources/default-config.yml
@@ -1,13 +1,4 @@
retrofit:
- # 连接池配置
- pool:
- # default连接池
- default:
- # 最大空闲连接数
- max-idle-connections: 5
- # 连接保活时间(秒)
- keep-alive-second: 300
-
# 全局转换器工厂
global-converter-factories:
- com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory
@@ -84,12 +75,3 @@ retrofit:
slow-call-duration-threshold-seconds: 60
# 启用可写堆栈跟踪的标志
writable-stack-trace-enabled: true
-
- # 全局连接超时时间
- global-connect-timeout-ms: 10000
- # 全局读取超时时间
- global-read-timeout-ms: 10000
- # 全局写入超时时间
- global-write-timeout-ms: 10000
- # 全局完整调用超时时间
- global-call-timeout-ms: 0