Retrofit 最新源码分析 2.10.0-SNAPSHOT

在这里插入图片描述

1. 介绍

Retrofit主要是基于OKHttp进一步封装的网络请求的框架。它采用了一种接口方法声明请求的方式,使用方法注解和方法参数注解进行标记请求信息,通过动态代理访问接口方法并解析Method,最后将请求信息汇总组装成okhttp3.Request对象,再根据接口方法返回值类型决定调用适配器(CallAdapter),内部通过okhttp3.Call.enqueue(…) 或okhttp3.Call.execute() 同步/异步请求,请求响应后通过转换器(Converter)把okhttp3.ResponseBody数据再进行一次转换得到最后的数据。

2.用法

这一小节通过一系列不同请求方式的代码来展示相关的用法。
主要分为6个文件,具体代码文件在最后面。

  • ServiceInterface.kt 声明接口请求
  • Main.kt 测试接口请求
  • ApiConverterFactory.java 转换器工厂类
  • ApiRequestBodyConverter.java 转为RequestBody对象转换器类 (@Part 参数对象转为RequestBody)
  • ApiResponseBodyConverter.java ResponseBody对象转换器类
  • HttpBinResponse.java ResponseBody装好后的数据类

2.1 基本用法

  • 1.GET 请求下载文件
  • 2.GET 请求
  • 3.GET 请求 查询?name=value
  • 4.GET 请求 查询?name
  • 5.POST 请求
  • 6.POST 请求 表单数据提交 name=“名字”&content=“内容”
  • 7.POST 请求 多部分表单提交 multipart/form-data

2.2 其他用法

    1. 通过@URL 请求一个不同地址的URL
    1. 通过Interceptor拦截器,实现动态设置不同BaseUrl

3. 源码

这一小节,通过一个post表单提交梳理下执行流程。以下是这个post请求的代码:分为三部分
    1. 接口请求声明部分
    1. Retrofit类构建,并返回接口的实现类部分
    1. 接口请求测试部分
interface ServiceInterface {
   
...
companion object {
   
        var BASE_URL = "http://www.httpbin.org/"
    }
@POST("/post")
    @FormUrlEncoded
    fun post(@Field("name") name:String,@Field("content") content:String): Call<ResponseBody>
...
}
public class Main {
   
...
private static ServiceInterface sServiceInterface
 = new Retrofit.Builder()
.baseUrl(ServiceInterface.Companion.getBASE_URL())
.client(new OkHttpClient.Builder().build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(ApiConverterFactory.create())
.build()
.create(ServiceInterface.class);
/**
     * Post请求,表单提交 @FormUrlEncoded @Field
     */
    @Test
    public void testPostFormUrlEncoded(){
   
        String s = null;
        try {
   
            Response<ResponseBody> response = sServiceInterface.post("名字","内容").execute();
            s = response.body().string();
        } catch (IOException e) {
   
            e.printStackTrace();
        }
        System.out.println(s);
    }
...
}

sServiceInterface.post("名字","内容").execute();开始分析
1.先看看sServiceInterface是怎么创建的?
2.再看看调用post("名字","内容")方法是怎么回事?
3.最后看下执行execute()是怎么样的?

开始分析1.
//先进入Retrofit#create(..)方法
public <T> T create(final Class<T> service) {
   
    return (T)
        Proxy.newProxyInstance(
            service.getClassLoader(),
            new Class<?>[] {
   service},
            new InvocationHandler() {
   
            ...
              @Override
              public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
   
               ...
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args); //看重点部分
              }
            });
//分析1结束,通过Proxy.newProxyInstance(..)动态代理获取接口ServiceInterface代理对象。
开始分析2.

从上一步的loadServiceMethod(method).invoke(args)开始分为2个部分:

  • 2.1 loadServiceMethod(method)
  • 2.2 调用invoke(args)方法
开始分析2.1 loadServiceMethod(method)
 //从Retrofit#loadServiceMethod(..)开始
  ServiceMethod<?> loadServiceMethod(Method method) {
   
       ...
        result = ServiceMethod.parseAnnotations(this, method);
       ...
    }
    return result;
  }
//ServiceMethod#parseAnnotations(..)
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
   
    //解析生成RequestFactory对象,具体流程在【流程图】图片有描述
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

//HttpServiceMethod.parseAnnotations(..)
  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
   
    ...
      adapterType = method.getGenericReturnType();
    ...
  //获取调用适配器CallAdapter对象,具体流程在【流程图】图片有描述
    CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
    Type responseType = callAdapter.responseType();
    ...
  //获取转换器Converter对象,具体流程在【流程图】图片有描述
    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType)
retrofit-spring-boot-starter是一个用于整合Retrofit库和Spring Boot的starter项目,它可以简化在Spring Boot中使用Retrofit的配置和使用。 以下是retrofit-spring-boot-starter的使用方法: 1. 在你的Spring Boot项目的pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>com.github.lianjiatech</groupId> <artifactId>retrofit-spring-boot-starter</artifactId> <version>1.0.0</version> </dependency> ``` 2. 创建一个接口,用于定义Retrofit的API接口。例如: ```java import retrofit2.http.GET; import retrofit2.http.Path; public interface MyApi { @GET("/users/{username}") User getUser(@Path("username") String username); } ``` 3. 在你的Spring Boot应用程序中,使用`@Autowired`注解将Retrofit的API接口注入到你的代码中。例如: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import retrofit2.Retrofit; @Service public class MyService { private final MyApi myApi; @Autowired public MyService(Retrofit retrofit) { this.myApi = retrofit.create(MyApi.class); } public User getUser(String username) { return myApi.getUser(username); } } ``` 4. 现在你可以在你的代码中使用`MyService`来调用Retrofit的API接口了。例如: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class MyController { private final MyService myService; @Autowired public MyController(MyService myService) { this.myService = myService; } @GetMapping("/users/{username}") public User getUser(@PathVariable String username) { return myService.getUser(username); } } ``` 以上是retrofit-spring-boot-starter的基本用法。你可以根据自己的需求进行配置和使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值