Skip to content

Commit d97b5cb

Browse files
Merge pull request #27 from LianjiaTech/develop
Develop
2 parents 5cc7011 + dd8416c commit d97b5cb

File tree

12 files changed

+251
-44
lines changed

12 files changed

+251
-44
lines changed

README.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<dependency>
4343
<groupId>com.github.lianjiatech</groupId>
4444
<artifactId>retrofit-spring-boot-starter</artifactId>
45-
<version>2.1.6</version>
45+
<version>2.1.7</version>
4646
</dependency>
4747
```
4848

@@ -588,18 +588,23 @@ You only need to implement the `NetworkInterceptor` interface and configure it a
588588

589589
`Retrofit` uses `Converter` to convert the object annotated with `@Body` into the request body, and the response body data into a `Java` object. The following types of `Converter` can be used:
590590

591-
- Gson: com.squareup.Retrofit:converter-gson
592-
- Jackson: com.squareup.Retrofit:converter-jackson
593-
- Moshi: com.squareup.Retrofit:converter-moshi
594-
- Protobuf: com.squareup.Retrofit:converter-protobuf
595-
- Wire: com.squareup.Retrofit:converter-wire
596-
- Simple XML: com.squareup.Retrofit:converter-simplexml
591+
- [Gson](https://github.com/google/gson): com.squareup.Retrofit:converter-gson
592+
- [Jackson](https://github.com/FasterXML/jackson): com.squareup.Retrofit:converter-jackson
593+
- [Moshi](https://github.com/square/moshi/): com.squareup.Retrofit:converter-moshi
594+
- [Protobuf](https://developers.google.com/protocol-buffers/): com.squareup.Retrofit:converter-protobuf
595+
- [Wire](https://github.com/square/wire): com.squareup.Retrofit:converter-wire
596+
- [Simple XML](http://simple.sourceforge.net/): com.squareup.Retrofit:converter-simplexml
597+
- [JAXB](https://docs.oracle.com/javase/tutorial/jaxb/intro/index.html): com.squareup.retrofit2:converter-jaxb
597598

598-
`Retrofit-spring-boot-starter` uses jackson to perform serialization conversion by default. You can directly configure `jackson` serialization rules through `spring.jackson.*`. For configuration, please refer to [Customize the Jackson ObjectMapper](https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#howto-customize-the-jackson-objectmapper)! **If you need to use other serialization methods, introduce the corresponding dependency in the project, and then configure the corresponding `ConverterFactory` as a spring bean**.
599+
`retrofit-spring-boot-starter` supports configuring the global `converter factory` through `retrofit.global-converter-factories`. The converter factory instance is first obtained from the Spring container. If it is not obtained, it is created by reflection. The default global data converter factory is `retrofit2.converter.jackson.JacksonConverterFactory`, you can directly configure the `jackson` serialization rules through `spring.jackson.*`, please refer to [Customize the Jackson ObjectMapper](https:/ /docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#howto-customize-the-jackson-objectmapper)!
599600

600-
**We can also implement our own `Converter` by extending the extension of `Converter.Factory`** and then configure the custom `Converter.Factory` as the `bean` of `spring`!
601+
```yaml
602+
retrofit:
603+
global-converter-factories:
604+
- retrofit2.converter.jackson.JacksonConverterFactory
605+
```
601606

602-
> The custom configuration of `Converter.Factory` has higher priority!
607+
For each Java interface, you can also specify the `Converter.Factory` used by the current interface through `converterFactories()` annotated by `@RetrofitClient`, and the specified converter factory instance is still preferentially obtained from the Spring container.
603608

604609

605610
## Other features

README_CN.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
<dependency>
4242
<groupId>com.github.lianjiatech</groupId>
4343
<artifactId>retrofit-spring-boot-starter</artifactId>
44-
<version>2.1.6</version>
44+
<version>2.1.7</version>
4545
</dependency>
4646
```
4747

@@ -605,18 +605,24 @@ public class SourceInterceptor extends BaseGlobalInterceptor {
605605

606606
`Retrofit`使用`Converter`将`@Body`注解标注的对象转换成请求体,将响应体数据转换成一个`Java`对象,可以选用以下几种`Converter`:
607607

608-
- Gson: com.squareup.Retrofit:converter-gson
609-
- Jackson: com.squareup.Retrofit:converter-jackson
610-
- Moshi: com.squareup.Retrofit:converter-moshi
611-
- Protobuf: com.squareup.Retrofit:converter-protobuf
612-
- Wire: com.squareup.Retrofit:converter-wire
613-
- Simple XML: com.squareup.Retrofit:converter-simplexml
608+
- [Gson](https://github.com/google/gson): com.squareup.Retrofit:converter-gson
609+
- [Jackson](https://github.com/FasterXML/jackson): com.squareup.Retrofit:converter-jackson
610+
- [Moshi](https://github.com/square/moshi/): com.squareup.Retrofit:converter-moshi
611+
- [Protobuf](https://developers.google.com/protocol-buffers/): com.squareup.Retrofit:converter-protobuf
612+
- [Wire](https://github.com/square/wire): com.squareup.Retrofit:converter-wire
613+
- [Simple XML](http://simple.sourceforge.net/): com.squareup.Retrofit:converter-simplexml
614+
- [JAXB](https://docs.oracle.com/javase/tutorial/jaxb/intro/index.html): com.squareup.retrofit2:converter-jaxb
614615

615-
`retrofit-spring-boot-starter`默认使用的是jackson进行序列化转换,你可以直接通过`spring.jackson.*`配置`jackson`序列化规则,配置可参考[Customize the Jackson ObjectMapper](https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#howto-customize-the-jackson-objectmapper)!**如果需要使用其它序列化方式,在项目中引入对应的依赖,再把对应的`ConverterFactory`配置成spring的bean即可**。
616+
`retrofit-spring-boot-starter`支持通过`retrofit.global-converter-factories`配置全局数据转换器工厂,转换器工厂实例优先从Spring容器获取,如果没有获取到,则反射创建。默认的全局数据转换器工厂是`retrofit2.converter.jackson.JacksonConverterFactory`,你可以直接通过`spring.jackson.*`配置`jackson`序列化规则,配置可参考[Customize the Jackson ObjectMapper](https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#howto-customize-the-jackson-objectmapper)!
616617

617-
**我们也可以通过继承`Converter.Factory`扩展实现自己的`Converter`**;然后将自定义的`Converter.Factory`配置成`spring`的`bean`!
618+
```yaml
619+
retrofit:
620+
# 全局转换器工厂
621+
global-converter-factories:
622+
- retrofit2.converter.jackson.JacksonConverterFactory
623+
```
618624

619-
> 自定义配置的`Converter.Factory`优先级更高!
625+
针对每个Java接口,还可以通过`@RetrofitClient`注解的`converterFactories()`指定当前接口采用的`Converter.Factory`,指定的转换器工厂实例依然优先从Spring容器获取。
620626

621627

622628
## 其他功能示例

pom.xml

Lines changed: 13 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.1.6</version>
9+
<version>2.1.7</version>
1010

1111
<name>retrofit-spring-boot-starter</name>
1212
<description>retrofit-spring-boot-starter</description>
@@ -113,6 +113,18 @@
113113
<version>${okhttp3.version}</version>
114114
<scope>test</scope>
115115
</dependency>
116+
<dependency>
117+
<groupId>com.squareup.retrofit2</groupId>
118+
<artifactId>converter-gson</artifactId>
119+
<version>${retrofit.version}</version>
120+
<scope>test</scope>
121+
</dependency>
122+
<dependency>
123+
<groupId>com.squareup.retrofit2</groupId>
124+
<artifactId>converter-jaxb</artifactId>
125+
<version>${retrofit.version}</version>
126+
<scope>test</scope>
127+
</dependency>
116128
<dependency>
117129
<groupId>com.squareup.okio</groupId>
118130
<artifactId>okio</artifactId>

src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/RetrofitClient.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.github.lianjiatech.retrofit.spring.boot.core.ErrorDecoder;
55
import com.github.lianjiatech.retrofit.spring.boot.interceptor.LogStrategy;
66
import org.slf4j.event.Level;
7+
import retrofit2.Converter;
78
import retrofit2.Retrofit;
89

910
import java.lang.annotation.*;
@@ -41,6 +42,14 @@
4142
*/
4243
String path() default "";
4344

45+
/**
46+
* 适用于当前接口的转换器工厂,优先级比全局转换器工厂更高。转换器实例优先从Spring容器获取,如果没有获取到,则反射创建。
47+
* Converter factory for the current interface, higher priority than global converter factory.
48+
* The converter instance is first obtained from the Spring container. If it is not obtained, it is created by reflection.
49+
*/
50+
Class<? extends Converter.Factory>[] converterFactories() default {};
51+
52+
4453
/**
4554
* When calling {@link Retrofit#create(Class)} on the resulting {@link Retrofit} instance, eagerly validate the
4655
* configuration of all methods in the supplied interface.

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ public static PrototypeInterceptorBdfProcessor prototypeInterceptorBdfProcessor(
5555

5656
@Bean
5757
@ConditionalOnMissingBean
58-
@Autowired
59-
public RetrofitConfigBean retrofitConfigBean(ObjectMapper objectMapper) throws IllegalAccessException, InstantiationException {
58+
public RetrofitConfigBean retrofitConfigBean() throws IllegalAccessException, InstantiationException {
6059
RetrofitConfigBean retrofitConfigBean = new RetrofitConfigBean(retrofitProperties);
6160
// Initialize the connection pool
6261
Map<String, ConnectionPool> poolRegistry = new ConcurrentHashMap<>(4);
@@ -86,14 +85,9 @@ public RetrofitConfigBean retrofitConfigBean(ObjectMapper objectMapper) throws I
8685
retrofitConfigBean.setCallAdapterFactories(callAdapterFactories);
8786

8887
// converterFactory
89-
List<Converter.Factory> converterFactories = new ArrayList<>();
90-
Collection<Converter.Factory> converterFactoryBeans = getBeans(Converter.Factory.class);
91-
if (!CollectionUtils.isEmpty(converterFactoryBeans)) {
92-
converterFactories.addAll(converterFactoryBeans);
93-
}
94-
JacksonConverterFactory defaultJacksonConverterFactory = JacksonConverterFactory.create(objectMapper);
95-
converterFactories.add(defaultJacksonConverterFactory);
96-
retrofitConfigBean.setConverterFactories(converterFactories);
88+
Class<? extends Converter.Factory>[] globalConverterFactories = retrofitProperties.getGlobalConverterFactories();
89+
retrofitConfigBean.setGlobalConverterFactoryClasses(globalConverterFactories);
90+
9791
// globalInterceptors
9892
Collection<BaseGlobalInterceptor> globalInterceptors = getBeans(BaseGlobalInterceptor.class);
9993
retrofitConfigBean.setGlobalInterceptors(globalInterceptors);
@@ -120,6 +114,7 @@ public RetrofitConfigBean retrofitConfigBean(ObjectMapper objectMapper) throws I
120114
return retrofitConfigBean;
121115
}
122116

117+
123118
@Bean
124119
@ConditionalOnMissingBean
125120
public ObjectMapper jacksonObjectMapper() {
@@ -128,6 +123,13 @@ public ObjectMapper jacksonObjectMapper() {
128123
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
129124
}
130125

126+
@Bean
127+
@ConditionalOnMissingBean
128+
@Autowired
129+
public JacksonConverterFactory jacksonConverterFactory(ObjectMapper objectMapper) {
130+
return JacksonConverterFactory.create(objectMapper);
131+
}
132+
131133

132134
private <U> Collection<U> getBeans(Class<U> clz) {
133135
try {
@@ -139,7 +141,6 @@ private <U> Collection<U> getBeans(Class<U> clz) {
139141
return null;
140142
}
141143

142-
143144
@Override
144145
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
145146
this.applicationContext = applicationContext;

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ public class RetrofitConfigBean {
2121

2222
private List<CallAdapter.Factory> callAdapterFactories;
2323

24-
private List<Converter.Factory> converterFactories;
25-
2624
private Map<String, ConnectionPool> poolRegistry;
2725

2826
private Collection<BaseGlobalInterceptor> globalInterceptors;
@@ -33,6 +31,8 @@ public class RetrofitConfigBean {
3331

3432
private ServiceInstanceChooserInterceptor serviceInstanceChooserInterceptor;
3533

34+
private Class<? extends Converter.Factory>[] globalConverterFactoryClasses;
35+
3636
public RetrofitProperties getRetrofitProperties() {
3737
return retrofitProperties;
3838
}
@@ -51,14 +51,6 @@ public void setCallAdapterFactories(List<CallAdapter.Factory> callAdapterFactori
5151
this.callAdapterFactories = callAdapterFactories;
5252
}
5353

54-
public List<Converter.Factory> getConverterFactories() {
55-
return converterFactories;
56-
}
57-
58-
public void setConverterFactories(List<Converter.Factory> converterFactories) {
59-
this.converterFactories = converterFactories;
60-
}
61-
6254
public Map<String, ConnectionPool> getPoolRegistry() {
6355
return poolRegistry;
6456
}
@@ -98,4 +90,12 @@ public ServiceInstanceChooserInterceptor getServiceInstanceChooserInterceptor()
9890
public void setServiceInstanceChooserInterceptor(ServiceInstanceChooserInterceptor serviceInstanceChooserInterceptor) {
9991
this.serviceInstanceChooserInterceptor = serviceInstanceChooserInterceptor;
10092
}
93+
94+
public Class<? extends Converter.Factory>[] getGlobalConverterFactoryClasses() {
95+
return globalConverterFactoryClasses;
96+
}
97+
98+
public void setGlobalConverterFactoryClasses(Class<? extends Converter.Factory>[] globalConverterFactoryClasses) {
99+
this.globalConverterFactoryClasses = globalConverterFactoryClasses;
100+
}
101101
}

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import com.github.lianjiatech.retrofit.spring.boot.retry.BaseRetryInterceptor;
99
import com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor;
1010
import org.springframework.boot.context.properties.ConfigurationProperties;
11+
import retrofit2.Converter;
12+
import retrofit2.converter.jackson.JacksonConverterFactory;
1113

1214
import java.util.LinkedHashMap;
1315
import java.util.Map;
@@ -47,7 +49,6 @@ public class RetrofitProperties {
4749
/**
4850
* 日志打印拦截器
4951
* Log print Interceptor
50-
*
5152
*/
5253
private Class<? extends BaseLoggingInterceptor> loggingInterceptor = DefaultLoggingInterceptor.class;
5354

@@ -63,6 +64,13 @@ public class RetrofitProperties {
6364
*/
6465
private boolean disableVoidReturnType = false;
6566

67+
/**
68+
* 全局转换器工厂,转换器实例优先从Spring容器获取,如果没有获取到,则反射创建。
69+
* global converter factories, The converter instance is first obtained from the Spring container. If it is not obtained, it is created by reflection.
70+
*/
71+
@SuppressWarnings("unchecked")
72+
private Class<? extends Converter.Factory>[] globalConverterFactories = (Class<? extends Converter.Factory>[]) new Class[]{JacksonConverterFactory.class};
73+
6674

6775
public Class<? extends BaseLoggingInterceptor> getLoggingInterceptor() {
6876
return loggingInterceptor;
@@ -123,4 +131,12 @@ public Class<? extends BaseRetryInterceptor> getRetryInterceptor() {
123131
public void setRetryInterceptor(Class<? extends BaseRetryInterceptor> retryInterceptor) {
124132
this.retryInterceptor = retryInterceptor;
125133
}
134+
135+
public Class<? extends Converter.Factory>[] getGlobalConverterFactories() {
136+
return globalConverterFactories;
137+
}
138+
139+
public void setGlobalConverterFactories(Class<? extends Converter.Factory>[] globalConverterFactories) {
140+
this.globalConverterFactories = globalConverterFactories;
141+
}
126142
}

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

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public class RetrofitFactoryBean<T> implements FactoryBean<T>, EnvironmentAware,
5050

5151
private ApplicationContext applicationContext;
5252

53+
private static final Map<Class<? extends Converter.Factory>, Converter.Factory> CONVERTER_FACTORIES_CACHE = new HashMap<>();
54+
5355
public RetrofitFactoryBean(Class<T> retrofitInterface) {
5456
this.retrofitInterface = retrofitInterface;
5557
}
@@ -323,13 +325,47 @@ private synchronized Retrofit getRetrofit(Class<?> retrofitClientInterfaceClass)
323325
callAdapterFactories.forEach(retrofitBuilder::addCallAdapterFactory);
324326
}
325327
// 添加Converter.Factory
326-
List<Converter.Factory> converterFactories = retrofitConfigBean.getConverterFactories();
328+
Class<? extends Converter.Factory>[] converterFactoryClasses = retrofitClient.converterFactories();
329+
Class<? extends Converter.Factory>[] globalConverterFactoryClasses = retrofitConfigBean.getGlobalConverterFactoryClasses();
330+
331+
List<Converter.Factory> converterFactories = getConverterFactories(converterFactoryClasses, globalConverterFactoryClasses);
327332
if (!CollectionUtils.isEmpty(converterFactories)) {
328333
converterFactories.forEach(retrofitBuilder::addConverterFactory);
329334
}
330335
return retrofitBuilder.build();
331336
}
332337

338+
private List<Converter.Factory> getConverterFactories(Class<? extends Converter.Factory>[] converterFactoryClasses, Class<? extends Converter.Factory>[] globalConverterFactoryClasses) throws IllegalAccessException, InstantiationException {
339+
List<Class<? extends Converter.Factory>> combineConverterFactoryClasses = new ArrayList<>();
340+
341+
if (converterFactoryClasses != null && converterFactoryClasses.length != 0) {
342+
combineConverterFactoryClasses.addAll(Arrays.asList(converterFactoryClasses));
343+
}
344+
345+
if (globalConverterFactoryClasses != null && globalConverterFactoryClasses.length != 0) {
346+
combineConverterFactoryClasses.addAll(Arrays.asList(globalConverterFactoryClasses));
347+
}
348+
349+
if (combineConverterFactoryClasses.isEmpty()) {
350+
return Collections.emptyList();
351+
}
352+
353+
List<Converter.Factory> converterFactories = new ArrayList<>();
354+
355+
for (Class<? extends Converter.Factory> converterFactoryClass : combineConverterFactoryClasses) {
356+
Converter.Factory converterFactory = CONVERTER_FACTORIES_CACHE.get(converterFactoryClass);
357+
if (converterFactory == null) {
358+
converterFactory = getBean(converterFactoryClass);
359+
if (converterFactory == null) {
360+
converterFactory = converterFactoryClass.newInstance();
361+
}
362+
CONVERTER_FACTORIES_CACHE.put(converterFactoryClass, converterFactory);
363+
}
364+
converterFactories.add(converterFactory);
365+
}
366+
return converterFactories;
367+
}
368+
333369

334370
@Override
335371
public void setEnvironment(Environment environment) {

0 commit comments

Comments
 (0)