retrofit 源碼分析

retrofit 源碼分析

源碼執(zhí)行流程

new Retrofit.Builder().baseUrl(xx).build()

基于retrofit 2.4.1

Retrofit.Builder()

創(chuàng)建retrofit實例對象卜朗,通過new Retrofit.Builder().build();Builder作為Retrofit的靜態(tài)內部類
Retrofit.Builder類有3個構造函數(shù),分別為

public static final class Builder {
...
    Builder(Platform platform) {
        this.platform = platform;
    }
    public Builder() { 
        this(Platform.get());
    }
    Builder(Retrofit retrofit) { ... }
...
}

只有無參的構造函數(shù)提供了外部訪問權限public,其它兩個都是包內訪問;通過platform.get()獲取Platform對象,我在android平臺使用涵卵,所以返回的是Android;代碼如下

class Platform {
    private static final Platform PLATFORM = findPlatform();

    static Platform get(){
        return PLATFORM;
    }
    private static Platform findPlatform() {
        try {
          Class.forName("android.os.Build");
          if (Build.VERSION.SDK_INT != 0) {
            return new Android();
          }
        } catch (ClassNotFoundException ignored) {
        }
        try {
          Class.forName("java.util.Optional");
          return new Java8();
        } catch (ClassNotFoundException ignored) {
        }
        return new Platform();
  }
}

baseUrl

Retrofit.Builder類中方法遵循鏈式調用規(guī)則(即方法返回this,使用.調用下一個方法)卸留;例如

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

baseUrl必須以'/'結尾

build()

Retrofit.Builder().build()通過建造者模式陶缺,創(chuàng)建Retrofit對象狈癞;
對相關變量進行初始化夯到,有CallFactory,CallAdapter.Factory,Converter.Factory,Executor,并以此為參數(shù)創(chuàng)建Retrofit

public Retrofit build() {
    if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
    }
    //CallFactory = OkHttpClient
    okhttp3.Call.Factory callFactory = this.callFactory;
    if (callFactory == null) {
        callFactory = new OkHttpClient();
    }
    //Executor = Android.MainThreadExecutor  
    Executor callbackExecutor = this.callbackExecutor;
    if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
    }  
    //CallAdapter.Factory = ExecutorCallAdapterFactory
    List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    //Converter.Factory = BuiltInConverters
    List<Converter.Factory> converterFactories =
          new ArrayList<>(1 + this.converterFactories.size());
    converterFactories.add(new BuiltInConverters());
    converterFactories.addAll(this.converterFactories);

    return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);

}

Platform.Android源碼:它是Platform的子類枣申,且是靜態(tài)內部類售葡;

static class Android extends Platform {
    @IgnoreJRERequirement // Guarded by API check.
    @Override boolean isDefaultMethod(Method method) {
      if (Build.VERSION.SDK_INT < 24) {
        return false;
      }
      return method.isDefault(); //false
    }

    @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);
      }
    }
  }

IHttp ihttp = retrofit.create(IHttp.class)

IHttp為使用者自定義接口,我自定義了post方法

public interface IHttp {
    @POST("{url}")
    Call<ResponseBody> post(@Path(value = "url", encoded = true) String url,
                            @HeaderMap Map<String, String> headers,
                            @Body RequestBody body);
}    

create()

通過retrofit.create獲取接口實例對象,此處使用了動態(tài)代理設計模式

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);
            }
            return loadServiceMethod(method).invoke(args);
          }
        });
}

其中,method.getDeclaringClass返回IHttp中post方法的返回值類型忠藤;

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;
  }

執(zhí)行接口方法,得到Call<ResponseBody>

調用接口的方法ihttp.post()挟伙,得到返回值;源碼中執(zhí)行到proxy.invoke(); loadServiceMethod(),最后執(zhí)行到serviceMethod.invoke();

ServiceMethod

ServiceMethod是抽象類模孩,子類是HttpServiceMethod; 同樣通過建造者模式獲取HttpServiceMethod對象

abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(method,
          "Method return type must not include a type variable or wildcard: %s", returnType);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

    return new HttpServiceMethod.Builder<Object, T>(retrofit, method).build();
  }

  abstract T invoke(@Nullable Object[] args);
}

//HttpServiceMethod.Builder像寒, 構造函數(shù)參數(shù)來源:method: Proxy.invoke的第二個參數(shù)
    Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit;
      this.method = method;
    }

    HttpServiceMethod<ResponseT, ReturnT> build() {
      requestFactory = RequestFactory.parseAnnotations(retrofit, method);//[1]

      callAdapter = createCallAdapter();//[2]
      responseType = callAdapter.responseType();
      if (responseType == Response.class || responseType == okhttp3.Response.class) {
        throw methodError(method, "'"
            + Utils.getRawType(responseType).getName()
            + "' is not a valid response body type. Did you mean ResponseBody?");
      }
      responseConverter = createResponseConverter();//[3]

      if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
        throw methodError(method, "HEAD method must use Void as response type.");
      }

      return new HttpServiceMethod<>(this);
    }

[1]requestFactory:解析網絡請求方式及請求地址路徑

在HttpServiceMethod.Builder.build()方法中烘豹,有解析注解的函數(shù)調用[1] requestFactory = RequestFactory.parseAnnotations(retrofit, method);

final class RequestFactory {
  static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
  }
}

//RequestFactory.Builder的構造函數(shù)只進行了變量賦值,此處省略代碼
RequestFactory build(){
    for (Annotation annotation : methodAnnotations){
        parseMethodAnnotation(annotation);
    }
    ...
    return new RequestFactory(this);
}
private void parseMethodAnnotation(Annotation annotation) {
    if (annotation instanceof DELETE) {
        parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
    }else if (annotation instanceof POST) { //我使用post
        parseHttpMethodAndPath("POST", ((POST) annotation).value(), true); //.value取出url地址诺祸;path路徑
    }
    ...
}
private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
    if (this.httpMethod != null) {
        throw methodError(method, "Only one HTTP method is allowed. Found: %s and %s.",
        this.httpMethod, httpMethod);
      }
    this.httpMethod = httpMethod;
    this.hasBody = hasBody;

    if (value.isEmpty()) {
        return;
    }

      // Get the relative URL path and existing query string, if present.
    int question = value.indexOf('?');
    if (question != -1 && question < value.length() - 1) {
        // Ensure the query string does not have any named parameters.
    String queryParams = value.substring(question + 1);
    Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
    if (queryParamMatcher.find()) {
        throw methodError(method, "URL query string \"%s\" must not have replace block. "
              + "For dynamic query parameters use @Query.", queryParams);
        }
    }

    this.relativeUrl = value;//通過注解取出
    this.relativeUrlParamNames = parsePathParameters(value);

}

[2]創(chuàng)建CallAdapter對象

在HttpServiceMethod.Builder.build()方法中外构,調用[2]創(chuàng)建CallAdapter對象
callAdapter = createCallAdapter();,實際上通過retrofit中CallAdapter.Factory變量獲取,也就是ExecutorCallAdapterFactory.get()

//HttpServiceMethod.Builder
private CallAdapter<ResponseT, ReturnT> createCallAdapter() {
    Type returnType = method.getGenericReturnType();
    Annotation[] annotations = method.getAnnotations();
    try {
        return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
    } catch (RuntimeException e) { 
        throw methodError(method, e, "Unable to create call adapter for %s", returnType);
    }
}

//Retrofit
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
}
//adapter= ExecutorCallAdapterFactory.get()
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

    int start = callAdapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);//ExecutorCallAdapterFactory.get()
      if (adapter != null) {
        return adapter; 
      }
    }

final class ExecutorCallAdapterFactory extends CallAdapter.Factory{
    ...
  @Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    //這就是HttpServiceMethod中的callAdapter
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }
    ...
}

[3]創(chuàng)建Converter對象

在HttpServiceMethod.Builder.build()方法中,調用[3]創(chuàng)建Converter對象
responseConverter = createResponseConverter()
實際上調用retrofit中的BuiltInConverters.responseBodyConverter

//HttpServiceMethod.Builder.java
private Converter<ResponseBody, ResponseT> createResponseConverter() {
    Annotation[] annotations = method.getAnnotations();
    try {
        return retrofit.responseBodyConverter(responseType, annotations);
    } catch (RuntimeException e) {
        throw methodError(method, e, "Unable to create converter for %s", responseType);
    }
}

//Retrofit.java
//Converter = BuiltInConverters.responseBodyConverter()
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
    return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
      @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
    checkNotNull(type, "type == null");
    checkNotNull(annotations, "annotations == null");

    int start = converterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      Converter<ResponseBody, ?> converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);//BuiltInConverters.responseBodyConverter()
    if (converter != null) {
        //noinspection unchecked
        return (Converter<ResponseBody, T>) converter;
    }
}

//BuiltInConverters.java
// converter = BufferingResponseBodyConverter.INSTANCE
final class BuiltInConverters extends Converter.Factory {
  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    if (type == ResponseBody.class) {
      return Utils.isAnnotationPresent(annotations, Streaming.class)
          ? StreamingResponseBodyConverter.INSTANCE
          : BufferingResponseBodyConverter.INSTANCE;
    }//
    if (type == Void.class) {
      return VoidResponseBodyConverter.INSTANCE;
    }
    return null;
  }
  ...
}

以上分析完ServiceMethod創(chuàng)建過程漠酿,主要節(jié)點在[1][2][3]中

動態(tài)代理invoke的執(zhí)行邏輯

loadServiceMethod(method).invoke(args)
loadServiceMethod()返回ServiceMethod對象赫粥,其invoke為抽象方法,子類HttpServiceMethod.invoke的具體實現(xiàn)如下

//HttpServiceMethod.java
@Override ReturnT invoke(@Nullable Object[] args) {
    return callAdapter.adapt(
        new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
//callAdapter為[2]ExecutorCallAdapterFactory.get()
//requestFacotry為[1]
//callFactory為retrofit.callFactory,就是Retrofit.Builder中的OkHttpClient
//responseConverter為[3]

final class OkHttpCall<T> implements Call<T>

//ExecutorCallAdapterFactory.java
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    ...
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }
//callbackExecutor為retrofit.callbackExecutor胃夏,就是Android.MainThreadExecutor
//call: OkHttpCall
      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
}

static final class ExecutorCallbackCall<T> implements Call<T> {
    ...  
}

在自定義的IHttp接口中轴或,post請求返回值為Call<ResponseBody>, ExecutorCallbackCall即是該返回值

執(zhí)行網絡請求

通過執(zhí)行ihttp.post()得到的Call對象,執(zhí)行call.enqueue()

enqueue為異步請求仰禀;execute為同步請求

call.enqueue

ExecutorCallbackCall代碼如下,是ExecutorCallAdapterFactory的內部類

//ExecutorCallAdapterFactory.java
static final class ExecutorCallbackCall<T> implements Call<T> {
    ...
//callbackExecutor為retrofit.callbackExecutor照雁,就是Android.MainThreadExecutor
//delegate: OkHttpCall
    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }
//callback:由使用者傳入,網絡請求回調
    @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) {
        ...
        }

        @Override public void onFailure(Call<T> call, final Throwable t) {
         ...        }
      });
    }
    ...
}

調用okhttp

OkHttpCall調用okhttp中api實現(xiàn)網絡請求答恶,并接收請求結果

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

    okhttp3.Call call;
    Throwable failure;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      call = rawCall;
      failure = creationFailure;
      if (call == null && failure == null) {
        try {
          call = rawCall = createRawCall();//[1]
        } catch (Throwable t) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }
    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }

    if (canceled) {
      call.cancel();
    }
    call.enqueue(new okhttp3.Callback() { //[2]
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response<T> response;
        try {
          response = parseResponse(rawResponse);//[3]
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }

        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }

      @Override public void onFailure(okhttp3.Call call, IOException e) {
        callFailure(e);
      }

      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
    });
}

//callFactory : OkHttpClient, retrofit中創(chuàng)建饺蚊,HttpServiceMethodz中傳入
//[1]
private okhttp3.Call createRawCall() throws IOException {
    okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
}

此處對requestFactory.create(args)進行說明

//RequestFactory.java
okhttp3.Request create(@Nullable Object[] args) throws IOException {
    RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
        contentType, hasBody, isFormEncoded, isMultipart);

    @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
    ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;

    int argumentCount = args != null ? args.length : 0;
    if (argumentCount != handlers.length) {
      throw new IllegalArgumentException("Argument count (" + argumentCount
          + ") doesn't match expected count (" + handlers.length + ")");
    }

    for (int p = 0; p < argumentCount; p++) {
      handlers[p].apply(requestBuilder, args[p]);
    }

    return requestBuilder.build();
}

requestBuilder.build()函數(shù)內調用okhttp3中api,拼裝請求信息

//[2]:通過okhttp3執(zhí)行enqueue,并創(chuàng)建okhttp3.Callback
//[3]:解析返回值
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);
    }

    ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
    try {
      T body = responseConverter.convert(catchingBody);//[4]
      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;
    }
}

//[4]responseConverter為BuiltInConverters.responseBodyConverter(),本次分析使用的是BufferingResponseBodyConverter

//BuiltInConverters.java
static final class BufferingResponseBodyConverter
      implements Converter<ResponseBody, ResponseBody> {
    static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();

    @Override public ResponseBody convert(ResponseBody value) throws IOException {
      try {
        // Buffer the entire body to avoid future I/O.
        return Utils.buffer(value);
      } finally {
        value.close();
      }
    }
}

//Utils.java, 此處涉及okhttp3悬嗓,下篇討論
static ResponseBody buffer(final ResponseBody body) throws IOException {
    Buffer buffer = new Buffer();//com.squareup.okio
    body.source().readAll(buffer);
    return ResponseBody.create(body.contentType(), body.contentLength(), buffer);
  }

回調

在ExecutorCallbackCall中污呼,delegate.enqueue傳入了匿名對象callback,匿名對象中由callbackExecutor.execute調用使用值傳入的callback

//ExecutorCallbackCall.class
@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為retrofit.callbackExecutor,就是Android.MainThreadExecutor    

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

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

至此,已分析完retrofit源碼包竹,其中核心邏輯涉及okhttp3燕酷,會單獨寫一篇進行分析

源碼設計模式

建造者模式(Builder Pattern)

將一個復雜對象的構建與它的表示分離,使同樣的構建過程可以創(chuàng)建不同的表示.
屬于創(chuàng)建型模式周瞎,它提供了一種創(chuàng)建對象的最佳方式苗缩。
何時使用:

  • 一些基本部件不會變,而其組合經常變化的時候声诸。

優(yōu)點:

  • 建造者獨立酱讶,易擴展
  • 便于控制細節(jié)風險

缺點:

  • 產品必須有共同點,范圍有限制
  • 如內部變化復雜双絮,會有很多的建造類

注意事項:與工廠模式的區(qū)別是:建造者模式更加關注與零件裝配的順序

結合retrofit源碼中的使用場景浴麻,進行舉例

retrofit中RetrofitHttpServiceMethod對象的創(chuàng)建就是通過建造者模式;
實現(xiàn)方式: 在類中創(chuàng)建靜態(tài)內部類Builder囤攀,Builder提供外部訪問權限软免,定義相關變量的set方法,并定義build函數(shù)最終創(chuàng)建外部類對象. Builder中函數(shù)遵循鏈式調用規(guī)則

//Retrofit.java
public static final class Builder {
    public Builder() {...}

    public Builder callFactory(okhttp3.Call.Factory factory) {
      this.callFactory = checkNotNull(factory, "factory == null");
      return this;
    }
    public Builder callbackExecutor(Executor executor) {
      this.callbackExecutor = checkNotNull(executor, "executor == null");
      return this;
    }
    ...
    //創(chuàng)建外部類對象
    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
      List<Converter.Factory> converterFactories =
          new ArrayList<>(1 + this.converterFactories.size());
      converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
//給各變量賦值焚挠,并以此為參數(shù)創(chuàng)建Retrofit對象
      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }
}

//Retrofit構造函數(shù)可見性為`default`,本包內可見
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
      @Nullable Executor callbackExecutor, boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
    this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
}

如果參數(shù)過多或不統(tǒng)一膏萧,可使用Builder為參數(shù)創(chuàng)建外部類,如HttpServiceMethod的創(chuàng)建方式

//HttpServiceMethod.java
static final class Builder<ResponseT, ReturnT> {
    ...
    HttpServiceMethod<ResponseT, ReturnT> build() {
        ...
        return new HttpServiceMethod<>(this);
    }
}

HttpServiceMethod(Builder<ResponseT, ReturnT> builder) {
    requestFactory = builder.requestFactory;
    callFactory = builder.retrofit.callFactory();
    callAdapter = builder.callAdapter;
    responseConverter = builder.responseConverter;
}

代理模式(Proxy Pattern)

屬于結構型模式
為其他對象提供一種代理以控制對這個對象的訪問

何時使用:

  • 程序可能不希望用戶直接訪問該對象,而是提供一個特殊的對象以控制對當前對象的訪問
  • 如果對象位于遠程主機上榛泛,需要為用戶提供訪問該遠程對象的能力
  • 如果一個對象(例如很大的圖像)需要很長時間才能完成加載

優(yōu)點:

  • 代理模式可以屏蔽用戶真正請求的對象蝌蹂,是用戶程序和正在的對象解耦
  • 使用代理來擔當那些創(chuàng)建耗時的對象的替身

缺點:
代理類和委托類實現(xiàn)相同的接口,同時要實現(xiàn)相同的方法曹锨。這樣就出現(xiàn)了大量的代碼重復孤个。如果接口增加一個方法,除了所有實現(xiàn)類需要實現(xiàn)這個方法外沛简,所有代理類也需要實現(xiàn)此方法齐鲤。增加了代碼維護的復雜度。

靜態(tài)代理

需要定義接口或者父類,被代理對象與代理對象一起實現(xiàn)相同的接口或者是繼承相同父類.

注意:代理對象與目標對象要實現(xiàn)相同的接口,然后通過調用相同的方法來調用目標對象的方法

public interface IUserDao {
    void save();
}
//目標對象
public class UserDao implements IUserDao {
    public void save() {
        System.out.println("----已經保存數(shù)據!----");
    }
}
//代理對象
public class UserDaoProxy implements IUserDao{
    //接收保存目標對象
    private IUserDao target;
    public UserDaoProxy(IUserDao target){
        this.target=target;
    }

    public void save() {
        System.out.println("開始事務...");
        target.save();//執(zhí)行目標對象的方法
        System.out.println("提交事務...");
    }
}
public class App {
    public static void main(String[] args) {
        //目標對象
        UserDao target = new UserDao();
        //代理對象,把目標對象傳給代理對象,建立代理關系
        UserDaoProxy proxy = new UserDaoProxy(target);
        proxy.save();//執(zhí)行的是代理的方法
    }
}

動態(tài)代理

也叫JDK代理,接口代理

  • 在運行期椒楣,通過反射機制創(chuàng)建一個實現(xiàn)了一組給定接口的新類
  • 接口中聲明的所有方法都被轉移到調用處理器一個集中的方法中處理(InvocationHandler.invoke).在接口方法數(shù)量比較多的時候给郊,我們可以進行靈活處理,而不需要像靜態(tài)代理那樣每一個方法進行中轉捧灰。而且動態(tài)代理的應用使我們的類職責更加單一淆九,復用性更強
  • 在運行時生成的class,必須提供一組interface給它毛俏,然后該class就宣稱它實現(xiàn)了這些 interface

代理類所在包:java.lang.reflect.Proxy

static Object newProxyInstance(ClassLoader loader, Class [] interfaces, InvocationHandler handler)

注意該方法是在Proxy類中是靜態(tài)方法,且接收的三個參數(shù)依次為:

  • ClassLoader loader:指定當前目標對象使用類加載器,用null表示默認類加載器
  • Class [] interfaces:需要實現(xiàn)的接口數(shù)組
  • InvocationHandler handler:調用處理器,執(zhí)行目標對象的方法時,會觸發(fā)調用處理器的方法,從而把當前執(zhí)行目標對象的方法作為參數(shù)傳入

java.lang.reflect.InvocationHandler:這是調用處理器接口炭庙,它自定義了一個 invoke 方法,用于集中處理在動態(tài)代理類對象上的方法調用拧抖,通常在該方法中實現(xiàn)對委托類的代理訪問煤搜。

// 該方法負責集中處理動態(tài)代理類上的所有方法調用免绿。第一個參數(shù)既是代理類實例唧席,第二個參數(shù)是被調用的方法對象
// 第三個方法是調用參數(shù)。
Object invoke(Object proxy, Method method, Object[] args)

retrofit中就是使用了動態(tài)代理模式嘲驾,調用時傳入.class對象,返回接口實例對象

//Retrofit.java
public <T> T create(final Class<T> 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);
            }
            return loadServiceMethod(method).invoke(args);
          }
        });
}

//IHttp為自定義接口
IHttp ihttp = retrofit.create(IHttp.class);

注解

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末淌哟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子辽故,更是在濱河造成了極大的恐慌徒仓,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件誊垢,死亡現(xiàn)場離奇詭異掉弛,居然都是意外死亡,警方通過查閱死者的電腦和手機喂走,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門殃饿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人芋肠,你說我怎么就攤上這事乎芳。” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵奈惑,是天一觀的道長吭净。 經常有香客問我,道長肴甸,這世上最難降的妖魔是什么寂殉? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮原在,結果婚禮上不撑,老公的妹妹穿的比我還像新娘。我一直安慰自己晤斩,他們只是感情好焕檬,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澳泵,像睡著了一般实愚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上兔辅,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天腊敲,我揣著相機與錄音,去河邊找鬼维苔。 笑死碰辅,一個胖子當著我的面吹牛,可吹牛的內容都是我干的介时。 我是一名探鬼主播没宾,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沸柔!你這毒婦竟也來了循衰?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤褐澎,失蹤者是張志新(化名)和其女友劉穎会钝,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體工三,經...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡迁酸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了俭正。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奸鬓。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖段审,靈堂內的尸體忽然破棺而出全蝶,到底是詐尸還是另有隱情闹蒜,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布抑淫,位于F島的核電站绷落,受9級特大地震影響,放射性物質發(fā)生泄漏始苇。R本人自食惡果不足惜砌烁,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望催式。 院中可真熱鬧函喉,春花似錦、人聲如沸荣月。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哺窄。三九已至捐下,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間萌业,已是汗流浹背坷襟。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留生年,地道東北人婴程。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像抱婉,于是被迫代替她去往敵國和親档叔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內容