Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

retrofit2 #7

Open
yunshuipiao opened this issue May 14, 2019 · 0 comments
Open

retrofit2 #7

yunshuipiao opened this issue May 14, 2019 · 0 comments

Comments

@yunshuipiao
Copy link
Owner

yunshuipiao commented May 14, 2019

Retrofit

A type-safe HTTP client for Android and Java

基于 version 2.5.0 进行分析。

Demo

官方使用文档

Retrofit 将 Http API 转换为 java 接口,因此可以做如下定义

public interface GitHubService {
  // 请求方法和地址
  @GET("users/{user}/repos")
  // 参数和返回值定义
  Call<List<Repo>> listRepos(@Path("user") String user);
}

生成 上述接口的实现类。

// 实例化 retrofit
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();
// 创建接口实现
GitHubService service = retrofit.create(GitHubService.class);

发起异步请求,之后交给 okhttp 来做底层处理,回到之前对 okhttp 请求过程的分析。

Call<List<Repo>> repos = service.listRepos("octocat");

下面就针对每一部分进行源码分析。

Retrofit

首先对 retrofit 实例的创建,用的是建造者模式。这里直接看最后的 build() 过程,直接了解配置了什么参数。

public Retrofit build() {
  if (baseUrl == null) {
    throw new IllegalStateException("Base URL required.");
  }
	
  // okhttp call 创建工厂,工厂模式的体现。
  // 将类实例化操作和使用对像的操作分开
  okhttp3.Call.Factory callFactory = this.callFactory;
  if (callFactory == null) {
    // okhttp 对象,用于创建 call
    callFactory = new OkHttpClient();
  }
	
  // 异步执行时进行回调
  Executor callbackExecutor = this.callbackExecutor;
  if (callbackExecutor == null) {
    callbackExecutor = platform.defaultCallbackExecutor();
  }

  // Make a defensive copy of the adapters and add the default Call adapter.
  // call 调用适配器,使得返回接口定义的返回值
  List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
  callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

  // Make a defensive copy of the converters.
  // 序列和反序列化转换器
  List<Converter.Factory> converterFactories = new ArrayList<>(
      1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

  // Add the built-in converter factory first. This prevents overriding its behavior but also
  // ensures correct behavior when using converters that consume all types.
  // 所有的转换器
  converterFactories.add(new BuiltInConverters());
  converterFactories.addAll(this.converterFactories);
  converterFactories.addAll(platform.defaultConverterFactories());
	
  return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
      unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}

interface

接着就可以实现之前声明的接口。

@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
// 最重要的部分
public <T> T create(final Class<T> service) {
  // 判断是接口并且不能继承其他接口
  Utils.validateServiceInterface(service);
  if (validateEagerly) {
    // 提前对 service 中的方法注解进行合法性验证
    eagerlyValidateMethods(service);
  }
  // 使用动态代理生成对应的 Service 
  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
      // 处理被代理对象的某个方法发生是调用,比如这里的 service 方法调用时进行回调
      new InvocationHandler() {
        private final Platform platform = Platform.get();
        private final Object[] emptyArgs = new Object[0];

        @Override public @Nullable Object invoke(Object proxy, Method method,
            @Nullable Object[] args) throws Throwable {
          // If the method is a method from Object then defer to normal invocation.
          if (method.getDeclaringClass() == Object.class) {
            return method.invoke(this, args);
          }
          if (platform.isDefaultMethod(method)) {
            return platform.invokeDefaultMethod(method, service, proxy, args);
          }
          return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
        }
      });
}
	// 加载 Service 并返回正在使用的方法
  ServiceMethod<?> loadServiceMethod(Method method) {
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        // 解析方法的注解, 获取请求方法的注解的所有信息
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

在上面的过程中,代理类解析方法的相关注解,包括 http 的请求方法, 地址,参数等信息,内容比较多,可以深入去看。下面就到了请求过程。

上次还提到动态代理, 当 service.listRepos("octocat") 时,接口中的调用会集中转发到 InvocationHandler 的 invoke() 方法,集中进行处理。

请求过程

当发生方法调用时,请求过程会来到如下代码:

@Override final @Nullable ReturnT invoke(Object[] args) {
  Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
  return adapt(call, args);
}

用相关的信息创建一个 okhttp 的 call 对象,

追下去就是 okhttp 的请求过程了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant