Spring4 Retrofit2 整合

来源:互联网 发布:交换机网络风暴 编辑:程序博客网 时间:2024/06/11 06:32

Spring4 Retrofit2 整合

组件结构

开始spring实例化bean后实例化带有HttpService注解的类(实际为retrofit动态代理类)结束

实现

1.构造retrofit工厂用于创建服务

Retrofit LoggingInterceptor日期拦截器

public class LoggingInterceptor implements Interceptor {    private static Logger logger = Logger.getLogger(LoggingInterceptor.class);    @Override    public Response intercept(Chain chain) throws IOException {        Request request = chain.request();        logger.info(String.format("发送请求:%s%n请求头:%s",                request.url(), request.headers()));        Response response = chain.proceed(request);        return response;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Retrofit FastJson转换器

public class FastJsonConverterFactory extends Converter.Factory{    public static FastJsonConverterFactory create() {        return new FastJsonConverterFactory();    }    /**     * 需要重写父类中responseBodyConverter,该方法用来转换服务器返回数据     */    @Override    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {        return new FastJsonResponseBodyConverter<>(type);    }    /**     * 需要重写父类中responseBodyConverter,该方法用来转换发送给服务器的数据     */    @Override    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {        return new FastJsonRequestBodyConverter<>();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
public class FastJsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {    private final Type type;    public FastJsonResponseBodyConverter(Type type) {        this.type = type;    }    /*    * 转换方法    */    @Override    public T convert(ResponseBody value) throws IOException {        BufferedSource bufferedSource = Okio.buffer(value.source());        String tempStr = bufferedSource.readUtf8();        bufferedSource.close();        try {            return JSON.parseObject(tempStr, type);        }catch (JSONException e){            return (T) tempStr;        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
public class FastJsonRequestBodyConverter<T> implements Converter<T, RequestBody> {    private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");    @Override    public RequestBody convert(T value) throws IOException {        return RequestBody.create(MEDIA_TYPE, JSON.toJSONBytes(value));    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

工厂生产的实体类

public class RetrofitBean {    private Retrofit retrofit;    private Map<Class,Object> service = new HashMap<>();    public Retrofit getRetrofit() {        return retrofit;    }    public void setRetrofit(Retrofit retrofit) {        this.retrofit = retrofit;    }    public Map<Class, Object> getService() {        return service;    }    public void setService(Map<Class, Object> service) {        this.service = service;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

工厂类

public class RetrofitBeanFactory {    //key:请求地址 value:当前请求地址下class所对应的service(key:class value:service)    private static Map<String, RetrofitBean> resolvableDependencies = new HashMap(16);    private static final int readTimeOut = 15;    private static final int writeTimeOut = 15;    private static final int connTimeOut = 15;    /**     * 获得service服务实体     *     * @param requiredType     * @return     * @throws BeansException     */    public static Object getBean(Class requiredType) throws BeansException {        for (Map.Entry<String, RetrofitBean> entrySet : resolvableDependencies.entrySet()) {            RetrofitBean retrofitBean = entrySet.getValue();            for (Map.Entry<Class, Object> serviceSet : retrofitBean.getService().entrySet()) {                if (requiredType == serviceSet.getKey()) {                    return serviceSet.getValue();                }            }        }        return null;    }    /**     * 创建service服务实体     *     * @param baseUrl     * @param serviceClass     */    public static Object putBean(String baseUrl, Class serviceClass, Class... interceptorClass) {        if (StringUtils.isEmpty(baseUrl)) {            return null;        }        RetrofitBean retrofitBean = resolvableDependencies.get(baseUrl);        //如果为空设置一个        if (retrofitBean == null) {            retrofitBean = new RetrofitBean();            OkHttpClient.Builder clientBuilder = new OkHttpClient().newBuilder()                    .connectTimeout(readTimeOut, TimeUnit.SECONDS)                    .writeTimeout(writeTimeOut, TimeUnit.SECONDS)                    .readTimeout(connTimeOut, TimeUnit.SECONDS)                    .addInterceptor(new LoggingInterceptor());            if (interceptorClass != null && interceptorClass.length > 0) {                for (Class clazz : interceptorClass) {                    if (Interceptor.class.isAssignableFrom(clazz)) {                        try {                            clientBuilder.addInterceptor((Interceptor) clazz.newInstance());                        } catch (InstantiationException e) {                            e.printStackTrace();                        } catch (IllegalAccessException e) {                            e.printStackTrace();                        }                    }                }            }            Retrofit retrofit = new Retrofit.Builder()                    .baseUrl(baseUrl)                    .client(clientBuilder.build())                    .addConverterFactory(FastJsonConverterFactory.create())                    .build();            retrofitBean.setRetrofit(retrofit);            resolvableDependencies.put(baseUrl, retrofitBean);        }        Retrofit retrofit = retrofitBean.getRetrofit();        Object bean = retrofit.create(serviceClass);        retrofitBean.getService().put(serviceClass, bean);        return bean;    }    public static Map<String, RetrofitBean> getResolvableDependencies() {        return resolvableDependencies;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77

2.扩展spring生命周期

自定义配置文件读取工具

public class CustomPropertyPlaceholderConfigurer extends        PropertyPlaceholderConfigurer {    private Properties props;    @Override    protected void processProperties(            ConfigurableListableBeanFactory beanFactory, Properties props)            throws BeansException {        super.processProperties(beanFactory, props);        this.props = props;    }    public Object getProperty(String key) {        return props.get(key);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

自定义注解

/** * Created by zhangbowen on 2016/5/12. * 用于标识服务接口类 */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface HttpApi {    String value() default "";//通过key获得配置文件中的值    Class[] interceptor() default {};}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
/** * Created by zhangbowen on 2016/5/12. * 用于自动注入服务 */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface HttpService {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

spring注入实体后的回调方法

public class RetrofitAutowiredProcessor extends InstantiationAwareBeanPostProcessorAdapter {    private Logger logger = Logger.getLogger(RetrofitAutowiredProcessor.class);    @Autowired    private CustomPropertyPlaceholderConfigurer propertyConfigurer;    @Override    public boolean postProcessAfterInstantiation(final Object bean, final String beanName) throws BeansException {        ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {            @Override            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {                HttpService httpApi = field.getAnnotation(HttpService.class);                if (httpApi == null) {                    return;                }                createRetrofitService(bean, field, field.getType());            }        });        return super.postProcessAfterInstantiation(bean, beanName);    }    private void createRetrofitService(Object bean, Field field, Class clazz) throws IllegalAccessException {        //读取注解中的值        HttpApi httpApi = (HttpApi) clazz.getAnnotation(HttpApi.class);        String key = httpApi.value();        if (StringUtils.isBlank(key)) {            return;        }        //根据注解的key获得配置文件中的url        Object value = propertyConfigurer.getProperty(key);        if (value == null) {            return;        }        //根据地址创建retrofit        Object object = RetrofitBeanFactory.putBean(value.toString(), clazz,httpApi.interceptor());        if (object == null) {            return;        }        field.setAccessible(true);        field.set(bean, object);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

3.在spring.config中注册组件

<!--注册加载retrofit服务的processor 只能在非controller中使用-->    <bean id="retrofitProcessor" class="com.miyan.common.modules.retrofit.processor.RetrofitAutowiredProcessor"></bean>
  • 1
  • 2

4. 使用

Maven

Spring的就不再引入,建议使用Spring4,引入retrofit2框架

 <dependency>      <groupId>com.squareup.retrofit2</groupId>      <artifactId>retrofit</artifactId>      <version>2.0.2</version> </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

properties

定义服务的地址

IM_BASE_URL=https://a1.easemob.com/huapingxin2015/miyan/
  • 1

创建retrofit服务接口

//IM_BASE_URL在配置文件中配置//interceptor 为可选参数,与retrofit拦截器相同,实现拦截http@HttpApi(value = "IM_BASE_URL", interceptor = {ImInterceptor.class})public interface IMApi { /**     * 修改群组信息     *     * @param updateGroupInfoBean     * @param groupId     * @return     */    @PUT("chatgroups/{group_id}")    Call<String> updateGroup(@Body UpdateGroupInfoBean updateGroupInfoBean, @Path("group_id") String groupId);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

ImInterceptor

/** * Created by zhangbowen on 2016/5/17. * 环信公用请求头拦截器 */public class ImInterceptor implements Interceptor {    @Override    public Response intercept(Chain chain) throws IOException {        Request originalRequest = chain.request();        String token = CacheFacade.getObject(Constants.IM.TOKEN);        Request request = originalRequest                .newBuilder()                .addHeader(Constants.Http.AUTHORIZATION, "Bearer " + token)                .build();        return chain.proceed(request);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在Service层中使用

/** * Created by zhangbowen on 2016/1/21. * 环信及时通讯服务 */@Servicepublic class IMService {    @HttpService    private IMApi imApi;      /**     * 修改群组信息     *     * @param updateGroupInfoBean     * @param groupId     */        public void updateGroupInfo(UpdateGroupInfoBean updateGroupInfoBean, String groupId) {            try {                imApi.updateGroup(updateGroupInfoBean, groupId).execute();            } catch (IOException e) {                e.printStackTrace();            }        }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

5.小结

仅仅是将retrofit整合进spring,并没有扩展retortfit功能,通过BeanPostProcessor的子实现类InstantiationAwareBeanPostProcessor的生命周期postProcessAfterInstantiation实现,其中用到的拦截器,定义服务接口中的注解以及请求都是retorfit2.0中提供的。retrofit2.0是Android中比较流行的网络框架,是对okhttp的再次封装 
与spring整合后,web应用中调用三方接口的网络请求会简单清晰很多,比自己封装的网络框架好很多 
附retorfit github: 
http://square.github.io/retrofit/

0 0
原创粉丝点击