自定义注解,通过配置获取 beseurl retrofit,自定义bean,注册bean
自定义bean类:
public class CustomBeanDefinition implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, ApplicationContextAware {
private ApplicationContext context;
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
private Map<String, Retrofit> retrofitMap = new HashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
context = applicationContext;
}
/**
* 从配置中获取retrofit信息,生成retrofit对象
*/
@Override
public void setEnvironment(Environment environment) {
String str = environment.getProperty("dev.retrofitList");
List<RetrofitInfo> retrofitInfoList = GsonUtils.toObject(str, new TypeToken<List<RetrofitInfo>>() {
}.getType());
for (RetrofitInfo retrofitInfo : retrofitInfoList) {
retrofitMap.put(retrofitInfo.getName(), getCreateRetrofit(retrofitInfo.getUrl(), retrofitInfo.getToken()));
}
}
/**
* 遍历RetrofitService注解,定义bean,添加retrofit属性,从retrofitMap中获取retrofit,注册bean
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
Reflections reflections = new Reflections("com.myspringboot.test.Service");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(RetrofitService.class);
for (Class<?> serviceClass : annotated) {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setLazyInit(true);
beanDefinition.setBeanClass(ServiceFactoryBean.class);
RetrofitService retrofitService = (RetrofitService) serviceClass.getAnnotations()[0];
Retrofit retrofit = retrofitMap.get(retrofitService.name());
if (retrofit != null) {
beanDefinition.getPropertyValues().addPropertyValue("retrofit", retrofit);
} else {
beanDefinition.getPropertyValues().addPropertyValue("retrofit", retrofitMap.get("p2p-core"));
}
beanDefinition.getPropertyValues().addPropertyValue("serviceClass", serviceClass);
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(serviceClass);
String beanName = this.beanNameGenerator.generateBeanName(abd, registry);
registry.registerBeanDefinition(beanName, beanDefinition);
}
}
public Retrofit getCreateRetrofit(String baseUrl, String token) {
final String basic = new String(Base64.encodeBase64(token.getBytes()));
/**
* Gson 反序列化 Date 处理
* Retrofit2 在反序列化 Date 时会调用 Gson 进行,
* 而 Gson 对于 Date的处理方式 会根据系统环境自动处理
* en_US下默认使用 iso8601Format("yyyy-MM-dd'T'HH:mm:ss'Z'") 格式化
* 为避免格式化错误(库里一般 yyyy-MM-dd hh:mm:ss),需要自定义转换
*/
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Date.class, (JsonDeserializer<Date>) (json, typeOfT, context) -> new Date(json.getAsJsonPrimitive().getAsLong()));
Gson gson = builder.create();
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(40, TimeUnit.SECONDS) //链接超时
.writeTimeout(40, TimeUnit.SECONDS) //写超时
.readTimeout(40, TimeUnit.SECONDS) //响应超时
.retryOnConnectionFailure(false) //取消重试
.addInterceptor(chain -> {
Request original = chain.request();
Span currentSpan = context.getBean(SpanAccessor.class).getCurrentSpan();
Request.Builder requestBuilder = original.newBuilder()
.header("Authorization", basic)
.header("Connection", "close") //关闭http keeplive 因为会引发错误 https://github.com/square/okhttp/issues/1517
.method(original.method(), original.body());
if (currentSpan != null) {
requestBuilder.header(Span.TRACE_ID_NAME, Span.idToHex(currentSpan.getTraceId()))
.header(Span.SPAN_NAME_NAME, currentSpan.getName())
.header(Span.SPAN_ID_NAME, Span.idToHex(currentSpan.getSpanId()));
}
Request request = requestBuilder.build();
return chain.proceed(request);
})
.build();
return new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(gson)) // 增加 Gson 时间处理(反序列化)
.client(okHttpClient)
.build();
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
@Configuration
@Import(CustomBeanDefinition.class)
public class CustomBeanConfig {
}
自定义注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RetrofitService {
String name() default "";
}
public class RetrofitInfo {
private String name;
private String url;
private String token;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}
配置文件
server:
port: 8011
message:
data:
name: dev
password: 1212
dev:
retrofitList: "[{'name': 'p2p-core' ,'url': 'http://xxx.xxx.com','token': '2ce49ff17e9447ee0f9b50b'},{'name': 'ms','url': 'http://xxx.xxxx.com','token': 'GYbBCtn7BKb'}]"