Retrofit源码分析笔记

Retrofit Version:2.2.0
分析代码地址:https://github.com/Blankeer/source-analysis-retrofit

  1. 环境配置相关:

    • 发现项目是基于Maven的,于是祭出许久不用的Idea
    • 删掉了部分对源码无用的配置文件,比如website/,CHANGELOG.md等
  2. samples分析

        public interface GitHub {
            @GET("/repos/{owner}/{repo}/contributors")
            Call> contributors(
                    @Path("owner") String owner,
                    @Path("repo") String repo);
        }
        // Create a very simple REST adapter which points the GitHub API.
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(API_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        // Create an instance of our GitHub API interface.
        GitHub github = retrofit.create(GitHub.class);
        // Create a call instance for looking up Retrofit contributors.
        Call> call = github.contributors("square", "retrofit");
        call.enqueue(new Callback>() {
            @Override
            public void onResponse(Call> call, Response> response) {
                for (Contributor contributor : response.body()) {
                    System.out.println(contributor.login + " (" + contributor.contributions + ")");
                }
            }
            @Override
            public void onFailure(Call> call, Throwable t) {
    
            }
        });
    

    这是最简单的用法,使用步骤:

    1. 定义一个 API 的 Interface.包含 API 的基本信息(url,method,path,call,返回类型等)
    2. 实例化Retrofit对象,配置 baseUrl 和 ConverterFactory
    3. 通过 retrofit.create 方法创建 API 实例对象
    4. 直接调用具体的 api 方法得到 Call 对象,调用enqueue方法传入回调
  3. 基本函数调用链

    • Retrofit.Build 建造者模式
    • Retrofit.create() 创建相应Api interface
      • eagerlyValidateMethods 校验解析所有method,即定义的每个api method
        • ServiceMethod.build() 解析interface所有method,每个method的参数封装成ServiceMethod
          • ServiceMethod.createCallAdapter() 每个method寻找匹配的CallAdapter,即返回值转换器
            • Retrofit.callAdapter() 遍历retrofit配置过的adapter,寻找匹配的那个
              • Retrofit.nextCallAdapter()
          • ServiceMethod.createResponseConverter() 创建response转换器
            • Retrofit.responseBodyConverter() 寻找匹配的responseConverter
              • Retrofit.nextResponseBodyConverter()
          • ServiceMethod.parseMethodAnnotation() 解析标记方法的每个注解,比如Get,Post等常见注解就是在这里解析
            • ServiceMethod.parseHttpMethodAndPath() 解析具体的Http注解和path,比如GET
              • ServiceMethod.parsePathParameters() 解析url包含的路径参数,即{path},params必须包含@Path
            • ServiceMethod.parseHeaders() 解析head,通过@Headers判断
          • ServiceMethod.parseParameter() 解析每个param,返回ParameterHandler
            • ServiceMethod.parseParameterAnnotation() 解析参数的具体注解,常见的有@path,@query等,requestConverter和stringConverter在这会被调用
              • ParameterHandler 这个类主要是api方法参数的各种具体处理,添加到RequestBuilder
      • Proxy.newProxyInstance() 动态代理,代理整个Api interface,当我们调用api方法时,会调用这个代理的invoke()方法,这是retrofit的核心
        • OkHttpCall OKHttp具体请求网络的地方,拿出初始化传入的OkHttpClient,拿出ServiceMethod.toRequest()的Request,然后怼到一起,调用okhttp的api进行网络请求和回调处理,在parseResponse()中会调用responseConverter
        • CallAdapter.adapt() Android默认的CallAdapter在ExecutorCallAdapterFactory里,返回的是Call,另外提供的有RxJava2CallAdapter,返回值是Observable
  4. 关键点的代码查看

    1. 为什么只用定义一个interface,达到直接调用的效果
      利用了Java动态代理机制,和 AOP 一个原理,相关代码在Retrofit.create();
          return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service},
                          new InvocationHandler() {
                              private final Platform platform = Platform.get();
                              @Override
                              public Object invoke(Object proxy, Method method, Object[] args)
                                      throws Throwable {
                                  //......
                                  //NOTE-Blanke: 加载这个method,如果设置validateEagerly=true,这里是直接获取serviceMethodCache里的缓存
                                  ServiceMethod serviceMethod =
                                          (ServiceMethod) loadServiceMethod(method);
                                  //NOTE-Blanke: 默认http调用OKHttp,这里可以扩展,换成别家的http框架
                                  OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
                                  return serviceMethod.callAdapter.adapt(okHttpCall);
                              }
                          });    
       
      
    2. 平常使用最多的是json,相关转换代码
      以Gson解析为例,相关代码在retrofit2.converter.gson.
      • requestConvert
        见GsonRequestBodyConverter
        具体的转换代码在ParameterHandler.Body,具体调用链是ServiceMethod.parseParameterAnnotation()->new Body,ServiceMethod.toRequest()->Body.apply();
      • responseConvert
        见GsonResponseBodyConverter
        具体转换代码在ServiceMethod.toResponse().具体调用链是OkHttpCall.parseResponse()->ServiceMethod.toResponse();
    3. 自定义CallAdapter相关
      默认的是ExecutorCallAdapterFactory匿名类,默认的返回类型是Call.
      调用链是Retrofit.create():serviceMethod.callAdapter.adapt(okHttpCall)
      RxJava是RxJava2CallAdapter,返回类型是Observable
      自定义demo见ErrorHandlingAdapter
    4. 发现的设计模式

      • 建造者模式 出现的Builder类
      • 工厂模式 以Factory结尾的类
      • 代理模式 ExecutorCallbackCall,Retrofit.create()用到了动态代理
      • 策略模式 Converter,CallAdapter等的实现
      • 适配器模式 ErrorHandlingAdapter.MyCallAdapter
      • 迭代器模式 ParameterHandler
      • 外观模式 Retrofit
    5. 你可能感兴趣的:(Retrofit源码分析笔记)