Retrofit - 13 ServiceMethod object analysis in retrofit

ServiceMethod serviceMethod = Retrofit.this.loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);

loadServiceMethod is actually loading ServiceMethod, which corresponds to a network request method defined in our interface, such as getCall, which is finally handed over to OKHTTP.

ServiceMethod<?, ?> loadServiceMethod(Method method) {
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;
    // A thread synchronization lock is set, mainly to ensure the data security of our thread.
    synchronized (serviceMethodCache) {
      /**
       * Get our ServiceMethod, this ServiceMethod is created using the singleton mode,
       * It actually has a serveMethodCache buffer pool for acquisition.
       */
      result = serviceMethodCache.get(method);
      /**
       * Non-empty judgment. If there is no cache, create a ServiceMethod object yourself,
       * It is created by the builder pattern Builder.
       */
      if (result == null) {
        // Finally call build() to create the creation of our actual ServiceMethod object.
        result = new ServiceMethod.Builder<>(this, method).build();
        /**
         * Put it in the cache pool, use the HTTP request method as the KEY,
         * The ServiceMethod object is stored in this buffer pool as VALUES.
         */
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

final class ServiceMethod<R, T> {
  // Upper and lower characters, digits, underscores, and hyphens, starting with a character.
  static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*";
  static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}");
  static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM);
  /**
   * network request factory, used to produce our network requests,
   * This call is actually our OKHTTP Call in Retrofit,
   * And OKHTTP Call is that Retrofit encapsulates it. It actually calls OKHTTP Call internally.
   */
  private final okhttp3.Call.Factory callFactory;
  // Network request adapter, adapt our Call request to different platforms. For example: RxJava etc.
  private final CallAdapter<R, T> callAdapter;

  private final HttpUrl baseUrl;
  // Data converter. The function is to convert the data returned by the server to us into the java Bean objects we need.
  private final Converter<ResponseBody, R> responseConverter;
  // HTTP methods for network requests, such as: get, post, put, etc.
  private final String httpMethod;
  // The relative address of the network request. Relative address + baseUrl = absolute address of the network request.
  private final String relativeUrl;
  // Request headers for HTTP network requests. key-value pair.
  private final Headers headers;
  // The body type of the HTTP network request message.
  private final MediaType contentType;
  private final boolean hasBody;
  private final boolean isFormEncoded;
  private final boolean isMultipart;
  // method parameter handler,
  private final ParameterHandler<?>[] parameterHandlers;
The ServiceMethod object actually contains all the basic information we need to access the network. It is covered. The following is its constructor.
ServiceMethod(Builder<R, T> builder) {
    this.callFactory = builder.retrofit.callFactory();
    this.callAdapter = builder.callAdapter;
    this.baseUrl = builder.retrofit.baseUrl ();
    this.responseConverter = builder.responseConverter;
    this.httpMethod = builder.httpMethod;
    this.relativeUrl = builder.relativeUrl;
    this.headers = builder.headers;
    this.contentType = builder.contentType;
    this.hasBody = builder.hasBody;
    this.isFormEncoded = builder.isFormEncoded;
    this.isMultipart = builder.isMultipart;
    this.parameterHandlers = builder.parameterHandlers;
  }

Next, let's take a look at the inner class Builder of ServiceMethod .

Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit;
      // Get the network request method (get, post, etc.)
      this.method = method;
      // Get the annotations in the network request interface method
      this.methodAnnotations = method.getAnnotations();
      // Get the type of the parameter in the network request interface method, it is a type.
      this.parameterTypes = method.getGenericParameterTypes();
      // Get the complete content of the annotations in the network request interface method
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    }

Next, let's take a look at the above line of code: result = new ServiceMethod.Builder<>(this, method).build();

Finally call build() to create the creation of our actual ServiceMethod object.


private CallAdapter<T, R> createCallAdapter() {
      //Get the return type in the network request interface method.
      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.");
      }
      //Get the annotations in the network request interface and call getAnnotations() in the reflection.
      Annotation[] annotations = method.getAnnotations();
      try {
        //noinspection unchecked. callAdapter(return value, annotation type)
        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);
      }












Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325907669&siteId=291194637