Skip to content

Commit 50941f1

Browse files
支持reactor、rxjava响应式编程
1 parent b871562 commit 50941f1

26 files changed

+1320
-110
lines changed

README.md

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter]
4848
<dependency>
4949
<groupId>com.github.lianjiatech</groupId>
5050
<artifactId>retrofit-spring-boot-starter</artifactId>
51-
<version>2.3.4</version>
51+
<version>2.3.5</version>
5252
</dependency>
5353
```
5454

@@ -59,7 +59,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter]
5959
<dependency>
6060
<groupId>com.github.lianjiatech</groupId>
6161
<artifactId>retrofit-spring-boot-starter</artifactId>
62-
<version>2.3.4</version>
62+
<version>2.3.5</version>
6363
</dependency>
6464
<dependency>
6565
<groupId>com.squareup.okhttp3</groupId>
@@ -145,14 +145,11 @@ public class TestService {
145145

146146
```yaml
147147
retrofit:
148-
# 全局转换器工厂
148+
# 全局转换器工厂(已经内置了组件扩展的转换器工厂,这里请勿重复配置)
149149
global-converter-factories:
150-
- com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory
151150
- retrofit2.converter.jackson.JacksonConverterFactory
152-
# 全局调用适配器工厂
151+
# 全局调用适配器工厂(已经内置了组件扩展的调用适配器工厂,这里请勿重复配置)
153152
global-call-adapter-factories:
154-
- com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory
155-
- com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory
156153

157154
# 全局日志打印配置
158155
global-log:
@@ -778,52 +775,72 @@ public class SourceGlobalInterceptor implements GlobalInterceptor {
778775
- `Response<T>`: 将响应内容适配成`Response<T>`对象返回!(不推荐)
779776
- `Call<T>`: 不执行适配处理,直接返回`Call<T>`对象!(不推荐)
780777

778+
**响应式编程支持**:
779+
780+
- `Mono<T>`: project-reactor响应式返回类型
781+
- `Single<T>`:rxjava响应式返回类型(支持rxjava2/rxjava3)
782+
- `Completable`:rxjava响应式返回类型,http请求没有响应体(支持rxjava2/rxjava3)
783+
784+
781785
```java
786+
@RetrofitClient(baseUrl = "${test.baseUrl}")
787+
public interface HttpApi {
782788
783-
/**
784-
* 其他任意Java类型
785-
* 将响应体内容适配成一个对应的Java类型对象返回,如果http状态码不是2xx,直接抛错!
786-
* @param id
787-
* @return
788-
*/
789-
@GET("person")
790-
Result<Person> getPerson(@Query("id") Long id);
789+
/**
790+
* 基础类型(`String`/`Long`/`Integer`/`Boolean`/`Float`/`Double`):直接将响应内容转换为上述基础类型。
791+
*/
792+
@POST("getString")
793+
String getString(@Body Person person);
791794

792-
/**
793-
* CompletableFuture<T>
794-
* 将响应体内容适配成CompletableFuture<T>对象返回
795-
* @param id
796-
* @return
797-
*/
798-
@GET("person")
799-
CompletableFuture<Result<Person>> getPersonCompletableFuture(@Query("id") Long id);
795+
/**
796+
* 其它任意POJO类型: 将响应体内容适配成一个对应的POJO类型对象返回,如果http状态码不是2xx,直接抛错!
797+
*/
798+
@GET("person")
799+
Result<Person> getPerson(@Query("id") Long id);
800800

801-
/**
802-
* Void
803-
* 不关注返回类型可以使用Void。如果http状态码不是2xx,直接抛错!
804-
* @param id
805-
* @return
806-
*/
807-
@GET("person")
808-
Void getPersonVoid(@Query("id") Long id);
801+
/**
802+
* `CompletableFuture<T>` :将响应体内容适配成CompletableFuture<T>对象返回,异步调用
803+
*/
804+
@GET("person")
805+
CompletableFuture<Result<Person>> getPersonCompletableFuture(@Query("id") Long id);
809806

810-
/**
811-
* Response<T>
812-
* 将响应内容适配成Response<T>对象返回
813-
* @param id
814-
* @return
815-
*/
816-
@GET("person")
817-
Response<Result<Person>> getPersonResponse(@Query("id") Long id);
807+
/**
808+
* `Void`: 不关注返回类型可以使用`Void`,如果http状态码不是2xx,直接抛错!
809+
*/
810+
@POST("savePerson")
811+
Void savePersonVoid(@Body Person person);
818812

819-
/**
820-
* Call<T>
821-
* 不执行适配处理,直接返回Call<T>对象
822-
* @param id
823-
* @return
824-
*/
825-
@GET("person")
826-
Call<Result<Person>> getPersonCall(@Query("id") Long id);
813+
/**
814+
* `Response<T>`:将响应内容适配成Response<T>对象返回
815+
*/
816+
@GET("person")
817+
Response<Result<Person>> getPersonResponse(@Query("id") Long id);
818+
819+
/**
820+
* `Call<T>`:不执行适配处理,直接返回Call<T>对象
821+
*/
822+
@GET("person")
823+
Call<Result<Person>> getPersonCall(@Query("id") Long id);
824+
825+
826+
/**
827+
* `Mono<T>` : project-reactor响应式返回类型
828+
*/
829+
@GET("person")
830+
Mono<Result<Person>> monoPerson(@Query("id") Long id);
831+
832+
/**
833+
* `Single<T>`:rxjava响应式返回类型(支持rxjava2/rxjava3)
834+
*/
835+
@GET("person")
836+
Single<Result<Person>> singlePerson(@Query("id") Long id);
837+
838+
/**
839+
* `Completable`:rxjava响应式返回类型,http请求没有响应体(支持rxjava2/rxjava3)
840+
*/
841+
@GET("ping")
842+
Completable ping();
843+
}
827844

828845
```
829846

pom.xml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.lianjiatech</groupId>
88
<artifactId>retrofit-spring-boot-starter</artifactId>
9-
<version>2.3.4</version>
9+
<version>2.3.5</version>
1010

1111
<name>retrofit-spring-boot-starter</name>
1212
<description>retrofit-spring-boot-starter</description>
@@ -172,6 +172,26 @@
172172
<version>1.7.1</version>
173173
<scope>provided</scope>
174174
</dependency>
175+
<dependency>
176+
<groupId>io.projectreactor</groupId>
177+
<artifactId>reactor-core</artifactId>
178+
<version>3.3.22.RELEASE</version>
179+
<scope>provided</scope>
180+
</dependency>
181+
<dependency>
182+
<groupId>io.reactivex.rxjava3</groupId>
183+
<artifactId>rxjava</artifactId>
184+
<version>3.1.5</version>
185+
<scope>provided</scope>
186+
</dependency>
187+
188+
<dependency>
189+
<groupId>io.reactivex.rxjava2</groupId>
190+
<artifactId>rxjava</artifactId>
191+
<version>2.2.21</version>
192+
<scope>provided</scope>
193+
</dependency>
194+
175195
</dependencies>
176196

177197
<distributionManagement>

src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,9 @@
1515
import com.fasterxml.jackson.databind.DeserializationFeature;
1616
import com.fasterxml.jackson.databind.ObjectMapper;
1717
import com.github.lianjiatech.retrofit.spring.boot.core.AutoConfiguredRetrofitScannerRegistrar;
18-
import com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory;
19-
import com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory;
2018
import com.github.lianjiatech.retrofit.spring.boot.core.Constants;
2119
import com.github.lianjiatech.retrofit.spring.boot.core.ErrorDecoder;
2220
import com.github.lianjiatech.retrofit.spring.boot.core.PathMatchInterceptorBdfProcessor;
23-
import com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory;
2421
import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitFactoryBean;
2522
import com.github.lianjiatech.retrofit.spring.boot.core.ServiceInstanceChooser;
2623
import com.github.lianjiatech.retrofit.spring.boot.core.SourceOkHttpClientRegistrar;
@@ -70,24 +67,6 @@ public SourceOkHttpClientRegistry sourceOkHttpClientRegistry(
7067
return new SourceOkHttpClientRegistry(sourceOkHttpClientRegistrars);
7168
}
7269

73-
@Bean
74-
@ConditionalOnMissingBean
75-
public BodyCallAdapterFactory bodyCallAdapterFactory() {
76-
return new BodyCallAdapterFactory();
77-
}
78-
79-
@Bean
80-
@ConditionalOnMissingBean
81-
public ResponseCallAdapterFactory responseCallAdapterFactory() {
82-
return new ResponseCallAdapterFactory();
83-
}
84-
85-
@Bean
86-
@ConditionalOnMissingBean
87-
public BasicTypeConverterFactory basicTypeConverterFactory() {
88-
return new BasicTypeConverterFactory();
89-
}
90-
9170
@Bean
9271
@ConditionalOnMissingBean
9372
public ErrorDecoder.DefaultErrorDecoder defaultErrorDecoder() {

src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import org.springframework.boot.context.properties.ConfigurationProperties;
44
import org.springframework.boot.context.properties.NestedConfigurationProperty;
55

6-
import com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory;
7-
import com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory;
86
import com.github.lianjiatech.retrofit.spring.boot.core.Constants;
9-
import com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory;
107
import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeProperty;
118
import com.github.lianjiatech.retrofit.spring.boot.log.GlobalLogProperty;
129
import com.github.lianjiatech.retrofit.spring.boot.retry.GlobalRetryProperty;
@@ -49,15 +46,13 @@ public class RetrofitProperties {
4946
* global converter factories, The converter instance is first obtained from the Spring container. If it is not obtained, it is created by reflection.
5047
*/
5148
@SuppressWarnings("unchecked")
52-
private Class<? extends Converter.Factory>[] globalConverterFactories = (Class<
53-
? extends Converter.Factory>[])new Class[] {BasicTypeConverterFactory.class, JacksonConverterFactory.class};
49+
private Class<? extends Converter.Factory>[] globalConverterFactories =
50+
(Class<? extends Converter.Factory>[])new Class[] {JacksonConverterFactory.class};
5451

5552
/**
5653
* 全局调用适配器工厂,转换器实例优先从Spring容器获取,如果没有获取到,则反射创建。
5754
* global call adapter factories, The callAdapter instance is first obtained from the Spring container. If it is not obtained, it is created by reflection.
5855
*/
5956
@SuppressWarnings("unchecked")
60-
private Class<? extends CallAdapter.Factory>[] globalCallAdapterFactories =
61-
(Class<? extends CallAdapter.Factory>[])new Class[] {BodyCallAdapterFactory.class,
62-
ResponseCallAdapterFactory.class};
57+
private Class<? extends CallAdapter.Factory>[] globalCallAdapterFactories = new Class[0];
6358
}

src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/BasicTypeConverterFactory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import java.lang.annotation.Annotation;
55
import java.lang.reflect.Type;
66

7+
import lombok.AccessLevel;
8+
import lombok.NoArgsConstructor;
79
import okhttp3.RequestBody;
810
import okhttp3.ResponseBody;
911
import retrofit2.Converter;
@@ -12,8 +14,11 @@
1214
/**
1315
* @author 陈添明
1416
*/
17+
@NoArgsConstructor(access = AccessLevel.PRIVATE)
1518
public final class BasicTypeConverterFactory extends Converter.Factory {
1619

20+
public static final BasicTypeConverterFactory INSTANCE = new BasicTypeConverterFactory();
21+
1722
@Override
1823
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
1924
Annotation[] methodAnnotations, Retrofit retrofit) {

src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/BodyCallAdapterFactory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
import com.github.lianjiatech.retrofit.spring.boot.exception.RetrofitException;
2222

23+
import lombok.AccessLevel;
24+
import lombok.NoArgsConstructor;
2325
import okhttp3.Request;
2426
import okhttp3.ResponseBody;
2527
import retrofit2.Call;
@@ -35,8 +37,11 @@
3537
*
3638
* @author 陈添明
3739
*/
40+
@NoArgsConstructor(access = AccessLevel.PRIVATE)
3841
public final class BodyCallAdapterFactory extends CallAdapter.Factory {
3942

43+
public static final BodyCallAdapterFactory INSTANCE = new BodyCallAdapterFactory();
44+
4045
@Override
4146
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
4247
if (Call.class.isAssignableFrom(getRawType(returnType))) {

src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/ResponseCallAdapterFactory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
import com.github.lianjiatech.retrofit.spring.boot.exception.RetrofitException;
2424

25+
import lombok.AccessLevel;
26+
import lombok.NoArgsConstructor;
2527
import okhttp3.Request;
2628
import retrofit2.Call;
2729
import retrofit2.CallAdapter;
@@ -34,8 +36,11 @@
3436
*
3537
* @author 陈添明
3638
*/
39+
@NoArgsConstructor(access = AccessLevel.PRIVATE)
3740
public final class ResponseCallAdapterFactory extends CallAdapter.Factory {
3841

42+
public static final ResponseCallAdapterFactory INSTANCE = new ResponseCallAdapterFactory();
43+
3944
@Override
4045
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
4146
if (Response.class.isAssignableFrom(getRawType(returnType))) {

src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
import org.springframework.util.StringUtils;
2222

2323
import com.github.lianjiatech.retrofit.spring.boot.config.RetrofitConfigBean;
24+
import com.github.lianjiatech.retrofit.spring.boot.core.reactive.MonoCallAdapterFactory;
25+
import com.github.lianjiatech.retrofit.spring.boot.core.reactive.Rxjava2CompletableCallAdapterFactory;
26+
import com.github.lianjiatech.retrofit.spring.boot.core.reactive.Rxjava2SingleCallAdapterFactory;
27+
import com.github.lianjiatech.retrofit.spring.boot.core.reactive.Rxjava3CompletableCallAdapterFactory;
28+
import com.github.lianjiatech.retrofit.spring.boot.core.reactive.Rxjava3SingleCallAdapterFactory;
2429
import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeProxy;
2530
import com.github.lianjiatech.retrofit.spring.boot.degrade.RetrofitDegrade;
2631
import com.github.lianjiatech.retrofit.spring.boot.interceptor.BasePathMatchInterceptor;
@@ -162,12 +167,58 @@ private Retrofit createRetrofit() {
162167

163168
combineAndCreate(retrofitClient.callAdapterFactories(), retrofitConfigBean.getGlobalCallAdapterFactoryClasses())
164169
.forEach(retrofitBuilder::addCallAdapterFactory);
170+
addReactiveCallAdapterFactory(retrofitBuilder);
171+
retrofitBuilder.addCallAdapterFactory(ResponseCallAdapterFactory.INSTANCE);
172+
retrofitBuilder.addCallAdapterFactory(BodyCallAdapterFactory.INSTANCE);
165173

174+
retrofitBuilder.addConverterFactory(BasicTypeConverterFactory.INSTANCE);
166175
combineAndCreate(retrofitClient.converterFactories(), retrofitConfigBean.getGlobalConverterFactoryClasses())
167176
.forEach(retrofitBuilder::addConverterFactory);
177+
168178
return retrofitBuilder.build();
169179
}
170180

181+
private void addReactiveCallAdapterFactory(Retrofit.Builder retrofitBuilder) {
182+
if (reactor3ClassExist()) {
183+
retrofitBuilder.addCallAdapterFactory(MonoCallAdapterFactory.INSTANCE);
184+
}
185+
if (rxjava2CalssExist()) {
186+
retrofitBuilder.addCallAdapterFactory(Rxjava2SingleCallAdapterFactory.INSTANCE);
187+
retrofitBuilder.addCallAdapterFactory(Rxjava2CompletableCallAdapterFactory.INSTANCE);
188+
}
189+
if (rxjava3ClassExist()) {
190+
retrofitBuilder.addCallAdapterFactory(Rxjava3SingleCallAdapterFactory.INSTANCE);
191+
retrofitBuilder.addCallAdapterFactory(Rxjava3CompletableCallAdapterFactory.INSTANCE);
192+
}
193+
}
194+
195+
private boolean rxjava3ClassExist() {
196+
try {
197+
Class.forName("io.reactivex.rxjava3.core.Single");
198+
return true;
199+
} catch (ClassNotFoundException e) {
200+
return false;
201+
}
202+
}
203+
204+
private boolean rxjava2CalssExist() {
205+
try {
206+
Class.forName("io.reactivex.Single");
207+
return true;
208+
} catch (ClassNotFoundException e) {
209+
return false;
210+
}
211+
}
212+
213+
private boolean reactor3ClassExist() {
214+
try {
215+
Class.forName("reactor.core.publisher.Mono");
216+
return true;
217+
} catch (ClassNotFoundException e) {
218+
return false;
219+
}
220+
}
221+
171222
private <E> List<E> combineAndCreate(Class<? extends E>[] clz, Class<? extends E>[] globalClz) {
172223
if (clz.length == 0 && globalClz.length == 0) {
173224
return Collections.emptyList();

0 commit comments

Comments
 (0)