retrofit实现(一)

自定义注解,通过配置获取 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'}]"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值