retrofit源码解析

准确来说,Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。

原因:网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装

 

App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求 参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作。

 

在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用 户的需求对结果进行解析。

一、整体架构分析

4

注意:

create的过程里没有使用动态代理

整体的架构就是

1、对网络参数的封装(协议、表单、restful)

2、封装Okhttp

3、数据结果封装

代码实例的创建过程

   Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("WWW.BAIDU.COM")
                .addConverterFactory(AAA)
                .build();
        retrofit.create(new classService);

 

成功建立一个Retrofit对象的标准:配置好Retrofit类里的成员变量

1、baseUrl:网络请求的url地址

不多解释这个


2、callFactory:网络请求工厂

3、adapterFactories:网络请求适配器工厂的集合

首先我们看一下初始化的build方法

retrofit是一个build的构建者设计模式,一般使用建造者模式,在构造函数里面有4-5个函数,且有可选参数,可以使用构造者模式来进行

retrofit本身是门面设计模式,对外的都是通过Retrofit来展示,内部封装了okhttp

build构建了一个okhttpclient,此处虽然是工厂模式,但是实际上默认用的就是okhttp,所以只支持okhttp

 public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }
     
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        //看此处。构建了一个okhttpclient
        callFactory = new OkHttpClient();
      }
       //线程管理器
//platform就是android平台
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
//添加一个默认的adapter
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }

Executor 是一个线程管理器。platfrom就是一个android平台,里面封装了主线程的handler,讲消息封装至主线程执行

static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
      if (callbackExecutor == null) throw new AssertionError();
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {
//切换主线程,post发送
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

添加一个默认的adapter   defaultCallAdapterFactory,把okhttp转变成retrofit的

  CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    if (callbackExecutor != null) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }
    return DefaultCallAdapterFactory.INSTANCE;
  }

  CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    if (callbackExecutor != null) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }
    return DefaultCallAdapterFactory.INSTANCE;
  }

扩展:现在我们看一下create里的方法,产生了一个OkHttpCall,并封装返回了一个okhttp的adapter封装,

public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    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, @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);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

这里传进有什么用呢?就和下边adapt交相呼应,将okhttpcall封装了,ExecutorCallbackCall是封装后的类,带有同步异步各种请求,是对okhttp的封装

final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
  final Executor callbackExecutor;

  ExecutorCallAdapterFactory(Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

  @Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }
 static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;

    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

    @Override public void enqueue(final Callback<T> callback) {
      checkNotNull(callback, "callback == null");

      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(new Runnable() {
//
            @Override public void run() {
              if (delegate.isCanceled()) {
                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
              } else {
                callback.onResponse(ExecutorCallbackCall.this, response);
              }
            }
          });
        }

        @Override public void onFailure(Call<T> call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
//切换到主线程
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

    @Override public boolean isExecuted() {
      return delegate.isExecuted();
    }

    @Override public Response<T> execute() throws IOException {
      return delegate.execute();
    }

    @Override public void cancel() {
      delegate.cancel();
    }

    @Override public boolean isCanceled() {
      return delegate.isCanceled();
    }

    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
    @Override public Call<T> clone() {
      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

    @Override public Request request() {
      return delegate.request();
    }
  }
}

回到我们之前的思路,就是封装了okhttp的封装,如果传入的不是默认的adapter,如果我们用的是rxjava,我么就可以将okhttp封装成obseverble;

converterFactories就是将okhttp的参数转换成retrofit的参数,可以在初始化的时候自己定义转换的方式,一般我们使用gson

  public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

至此,build构建过程完成了,看一下下面的流程,做了下面的一些事情

 

 

然后、创建了一个ISharedListService 接口类的对象,create函数内部使用了动态代理来创建接口对象,这样的设计可以让所有的访问请求都被代理

\

Call sharedListCall = sharedListService.getSharedList(2,1);

调用getSharedList的时候,在动态代理里面,会存在一个函数 getSharedList,这个函数里面会调 用 invoke,这个invoke函数也就是retrofit里面 invoke函数。所以,动态代理可以代理所有的接口,让所有的接口都走 invoke函数,这样就可以拦截调用函数 的执行,从而将网络接口的参数配置归一化。

实现原理和这个差不多,都是在create里面动态代理实现监听封装。执行invoke函数就会拦截,使用serviceMethod来进行处理

反射+注解+retrofit+okhttp3总结

在这里,默认是封装成了ExecutorCallbackCall,使用adapt方法

public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    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, @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);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

难点就在与loadServiceMethod进行参数适配,里面使用了缓存,为了减少反射产生的性能影响

  ServiceMethod<?, ?> loadServiceMethod(Method method) {
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

在nextCallAdapter里面可以看见这里是要从adapterFactories里面获取我们需要的adapter封装类,根据retrunType来看是哪一个adapter,这个是反射获取的,记得吗,我们事有一个默认的

  final class ServiceMethod<R, T> {
...

     public ServiceMethod build() {
      callAdapter = createCallAdapter();
    }
...
private CallAdapter<T, R> createCallAdapter() {
      Type returnType = method.getGenericReturnType();
      if (Utils.hasUnresolvableType(returnType)) {
        throw methodError(
            "Method return type must not include a type variable or wildcard: %s", returnType);
      }
      if (returnType == void.class) {
        throw methodError("Service methods cannot return void.");
      }
      Annotation[] annotations = method.getAnnotations();
      try {
        return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(e, "Unable to create call adapter for %s", returnType);
      }
    }

}


public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
  }

public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

    int start = adapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
      CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }
  public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      adapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

然后在serviceMethod的build的方法进行反射解析,不详细解释了

 for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }

至此完成了这个操作,下面那个红色的圈内就是这么实现的

3、callbackExecutor:回调方法执行器

 

接下来我们可以利用create生辰的api类,可以执行enqueue方法,这个方法会调用默认的adapter里面,也就是封装的ExecutorCallbackCall

delegate是之前在动态代理里面调用反射,使用adapt传过来的OkHttpCall,是对okhttp3的封装,所以这里也是使用OkHttpCall的方法,然后调用okhttp的enqueque

okhttp3具体原理看这里

 @Override public void enqueue(final Callback<T> callback) {
      checkNotNull(callback, "callback == null");
        
      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              if (delegate.isCanceled()) {
                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
              } else {
                callback.onResponse(ExecutorCallbackCall.this, response);
              }
            }
          });
        }

        @Override public void onFailure(Call<T> call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

回调之后,就会回调到最上层使用,这里面加入了线程切换

callbackExecutor.execute

在build里面传归来的,实际上就是PlatForm里面的线程切换

rxjava线程切换看这里、其实这里并不算是rxjava的切换,而是handler的主线程切换

  static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
      if (callbackExecutor == null) throw new AssertionError();
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

至此。请求、封装、回调调用完成

 

5、converterFactories:数据转换器工厂的集合

 Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    // Remove the body's source (the only stateful object) so we can pass the response along.
    rawResponse = rawResponse.newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

    int code = rawResponse.code();
    if (code < 200 || code >= 300) {
      try {
        // Buffer the entire body to avoid future I/O.
        ResponseBody bufferedBody = Utils.buffer(rawBody);
        return Response.error(bufferedBody, rawResponse);
      } finally {
        rawBody.close();
      }
    }

    if (code == 204 || code == 205) {
      rawBody.close();
      return Response.success(null, rawResponse);
    }

    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
    try {
///看这里,又调用了servicemethod的方法进行传还
      T body = serviceMethod.toResponse(catchingBody);
      return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
      // If the underlying source threw an exception, propagate that rather than indicating it was
      // a runtime exception.
      catchingBody.throwIfCaught();
      throw e;
    }
  }

 T body = serviceMethod.toResponse(catchingBody);、

在okHttpCall里面,调用了serviceMethod。为什么要用这个呢,因为所有的转换器保存在retrofit里面,然后create的时候,servicemethod获得了其引用,并在内部可以获取到我们之前传入的转换器

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值