Retrofit原理分析

创建Retrofit实例

 new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

  • 先看一下Retrofit的实例化
 new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

这个就是配置一下baseUrl,转换工程,然后设置到Retrofit这个创建出来的实例对象(源码如下)

//baseURL
public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      return baseUrl(HttpUrl.get(baseUrl));
    }
 public Builder baseUrl(HttpUrl baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      List pathSegments = baseUrl.pathSegments();
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
    }

这样就给retrofit的baseUrl赋值了,剩下的addConverterFactory,callAdapterFactory就不再贴源码了

然后通过Retrofit.Build()...build()生成Retrofit实例

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

      // Make a defensive copy of the adapters and add the default Call adapter.
      List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

      // Make a defensive copy of the converters.
      List 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);
    }

这个build()方法就是给Retrofit装备数据,然后生成Retrofit(由于每次对象都是new出来的所以我们用单利的设计模式,或者自己去做缓存啥的,保证唯一就行了)

到目前为止Retrofit的创建已经完成了;这儿使用的是Builder设计模式

生成对应的service(其实不是我们写的Service的类,而是动态代理生成的他的子类)

retrofit.create(ServiceClass.class)
  • Retrofit的create源码
public  T create(final Class 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();
          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不再是我们的service,而是动态代理生成的对象(具体的话看一下动态代理的原理就知道了)


retofit_pic1.png
  • 然后会执行到loadServerMethod方法
  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;
  }

先取缓存(ConCurrentHasMap-线程安全的)ServiceMethod,如果没有就生成一个新的ServiceMethod(这儿就是我们为什么Retrofit要进行单利模式了)

  • ServiceMethod.parseAnnotations()生成新的ServiceMethod
static  ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, 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 HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

先通过RequestFactory.parseAnnotations来进行解析这个方法,生成RequestFactory

static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
  }
  
RequestFactory build() {
    //就是方法注解解析(GET,POST等),然后配置参数(httpMethod,hasBody,relativeUrl,relativeUrlParamNames)
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }
        ...省略一些代码
        //参数注解解析(QUERY,BODY等)
      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler[parameterCount];
      for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
        parameterHandlers[p] =
            parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
      }
  ...省略一些代码
      return new RequestFactory(this);
    }
  • 方法注解解析自己去看一下源码就明白了没什么,就是解析,然后装配装备参数
private void parseMethodAnnotation(Annotation annotation) {
    //判断是哪个注解,然后配置对应的参数,
      if (annotation instanceof DELETE) {
        parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
      }
        ...省略
    }
    
  • 参数的注解解析
 private @Nullable ParameterHandler parseParameter(
        int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
      ParameterHandler result = null;
      if (annotations != null) {
        for (Annotation annotation : annotations) {
          ParameterHandler annotationAction =
              parseParameterAnnotation(p, parameterType, annotations, annotation);
        ...省略
        }
      }

    }
    //分析一种注解Query
      @Nullable
 private ParameterHandler parseParameterAnnotation( int p, Type type, Annotation[] annotations, Annotation annotation) {
   ...省略
   else if (annotation instanceof Query) {
               validateResolvableType(p, type);
               Query query = (Query) annotation;
               String name = query.value();
               boolean encoded = query.encoded();
       
               Class rawParameterType = Utils.getRawType(type);
               gotQuery = true;
               if (Iterable.class.isAssignableFrom(rawParameterType)) {
                 if (!(type instanceof ParameterizedType)) {
                   throw parameterError(method, p, rawParameterType.getSimpleName()
                       + " must include generic type (e.g., "
                       + rawParameterType.getSimpleName()
                       + ")");
                 }
                 ParameterizedType parameterizedType = (ParameterizedType) type;
                 Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
                 Converter converter =
                     retrofit.stringConverter(iterableType, annotations);
                 return new ParameterHandler.Query<>(name, converter, encoded).iterable();
               } else if (rawParameterType.isArray()) {
                 Class arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
                 //retrofit.stringConverter转化成Converter,如果你使用的是Query然后参数类型是自己定义的Bean的话,这个时候就需要自己去定义一下stringConverter
                 //因为Android里面常用的GsonConverter是没有重写这个方法的,这样是传过去(应用地址的值)是不对的
                 Converter converter =
                     retrofit.stringConverter(arrayComponentType, annotations);
                 return new ParameterHandler.Query<>(name, converter, encoded).array();
               } else {
                 Converter converter =
                     retrofit.stringConverter(type, annotations);
                 return new ParameterHandler.Query<>(name, converter, encoded);
               }
       
             }
   ...省略
 }
  
   public  Converter stringConverter(Type type, Annotation[] annotations) {
     checkNotNull(type, "type == null");
     checkNotNull(annotations, "annotations == null");
     //如果说我们给的convterFactory没有重写stringConverter的话就会返回一个BuiltInConverters.ToStringConverter.INSTANCE
     for (int i = 0, count = converterFactories.size(); i < count; i++) {
       Converter converter =
           converterFactories.get(i).stringConverter(type, annotations, this);
       if (converter != null) {
         //noinspection unchecked
         return (Converter) converter;
       }
     }
 
     // Nothing matched. Resort to default converter which just calls toString().
     //noinspection unchecked
     return (Converter) BuiltInConverters.ToStringConverter.INSTANCE;
   }
   
   static final class ToStringConverter implements Converter {
       static final ToStringConverter INSTANCE = new ToStringConverter();
        //就是一个toString,所以对于引用的数据类型我们要进行传递的话,我们放在query或者path里面的话就要去添加一个ConverterFactory(重写里面的stringConverter)
       @Override public String convert(Object value) {
         return value.toString();
       }
     }
     
  • 上面我们值分析了一种注解Query(stringConverter转换的),而如果是Body的话使用的是requestConverter,这里皆不贴源码了,需要了解的自己去看吧

  • 最后生成一个RequestFactory实例(作用:解析注解(方法上面的注解,和参数上面的注解),配置对应的请求参数)

  • 接下来看ServiceMethod的生成过程,在ServiceMethod.parseAnnotations()方法里面会执行HttpServiceMethod.parseAnnotations()来生成ServiceMethod对象

static  HttpServiceMethod parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
    boolean continuationWantsResponse = false;
    boolean continuationBodyNullable = false;

   ...省略
   //获取Retrofit的CallAdapter
    CallAdapter callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
    Type responseType = callAdapter.responseType();
    ...省略
    //获取Retrofit的ConverterFactory里面的responseConverter
    Converter responseConverter =
        createResponseConverter(retrofit, method, responseType);

    //获取Retrofit的callFactory(也就是我们设置的client)
    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    //生成对应的ServiceMethod
    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod) new SuspendForResponse<>(requestFactory,
          callFactory, responseConverter, (CallAdapter>) callAdapter);
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod) new SuspendForBody<>(requestFactory,
          callFactory, responseConverter, (CallAdapter>) callAdapter,
          continuationBodyNullable);
    }
  }

到目前为止我们的ServiceMethod创建完了,然后我们看一种ServerMethod--CallAdapted

在动态代理里面会执行ServiceMethod的invoke方法,也就是HttpServiceMethod的invoke->CallAdapted.adapt方法->callAdapter.adapt方法

//HttpServiceMethod的invoke
 @Override final @Nullable ReturnT invoke(Object[] args) {
    Call call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }
  
 //CallAdapted.adapt
 @Override protected ReturnT adapt(Call call, Object[] args) {
       return callAdapter.adapt(call);
     }
 //callAdapter.adapt方法(这儿是DefaultCallAdapterFactory)
  return new CallAdapter>() {
       @Override public Type responseType() {
         return responseType;
       }
 
       @Override public Call adapt(Call call) {
           //如果没有线程的话就直接返回这个call,有的话就将call封装到线程里面
         return executor == null
             ? call
             : new ExecutorCallbackCall<>(executor, call);
       }
     };
 
 

callAdapter.adapt(call)--这个call就是OkHttpCall

  • 然后执行方法了
//这是kotlin语法
val weatherDetail = weatherService.weatherDetail("101030100")
//            serviceCallCache.add(weatherDetail)
            weatherDetail.enqueue(object :Callback{
                override fun onFailure(call: Call, t: Throwable) {

                }

                override fun onResponse(call: Call, response: Response) {
                    textView.text=response.body()?.data?.wendu
                }
            })

然后执行OkHttpCall的enqueue()方法

@Override public void enqueue(final Callback 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();
        } catch (Throwable t) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }

    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }

    if (canceled) {
      call.cancel();
    }
    //执行Okhttp的enqueue()然后进行回调
    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response response;
        try {
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }

        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }

      @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) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }
    });
  }

我们看到最终执行的是okHttp的enqueue()然后进行回调

  • 到这儿源码就分析完了,有没有一个大题的印象呢

总结

  • 先创建Retrofit;通过Retrofit.Builder().build()的方法创建,你可以添加自己的converterFactory,callAdapterFactory,callFactory(client)
  • 通过动态代理创建执行Call

1,指通过Retrofit.crete()

2,判断缓存有没有有的话直接执行ServiceMethod的invoke方法

3,没有缓存通过Retrofit.loadServiceMethod创建ServiceMethod

(1)先创建RequestFactory(解析注解,装配对应的请求参数)
(2)在通过HttpServiceMethod.parseAnnotations生成对应的ServiceMethod(里面会装配callAdapter,callFactory,requestFactory,responseConverter)

4,执行invoke生成call

(1) 执行的是HttpServiceMethod.invoker->CallAdapted.adapt->CompletableFutureCallAdapterFactory.adapt方法返回call

5 ,执行enqueue实际上是执行的OkHttp的enqueue方法,然后进行回调

如有错误请在下方留言,谢谢您的支持!

你可能感兴趣的:(Retrofit原理分析)