站在巨人的肩膀上 -- Retrofit源码解析(二)

上一篇 站在巨人的肩膀上 – Retrofit源码解析(一) 主要是从Retrofit使用的基本API角度,去理清源码中大致的流程,可以说Retrofit是对OkHttp框架做了非常完美的封装,使用了大量的设计模式,使得Retrofit成为了一个简单易上手的网络请求框架. 这一篇主要解决上一篇留下来的疑问.

Retrofit源码基于版本2.4.0

1.ServiceMethod.Builder类的build函数,调用createCallAdapter函数是怎么获取到callAdapter的?

从createCallAdapter函数出发,调用到Retrofit类的callAdapter函数


	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 {
        //noinspection unchecked
        //遍历 存放网络请求适配器工厂的集合callAdapterFactories,找到合适的网络请求适配器工厂并返回
        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);
      }
    }

callAdapter函数调用nextCallAdapter函数,主要遍历callAdapterFactories这个存放网络请求适配器工厂的集合,获取跟网络请求函数返回值Call<List< Contributor>>相关的网络请求适配器工厂,那callAdapterFactories是在哪里存入适配器工厂? 存入了哪些适配器工厂?


	public final class Retrofit {

		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");
		
		    //遍历存放网络请求适配器工厂的集合callAdapterFactories,找到合适的网络请求适配器工厂调用其get函数并返回CallAdapter实例
		    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);
		      if (adapter != null) {
		        return adapter;
		      }
		    }		

			...省略无关代码
		}
	}
	

callAdapterFactories是在Retrofit的构造函数中赋值的, 而Retrofit是通过Build模式创建的, 看Retrofit.Builder类的build函数


	public final class Retrofit {
		public static final class Builder {
			
			public Retrofit build() {

				...省略部分无关代码

				List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
		        //将MainThreadExecutor装载进ExecutorCallAdapterFactory工厂实例里,并将工厂实例添加进 网络请求适配器工厂的集合里
		        callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

				...省略部分无关代码

				 //Collections.unmodifiableList()函数是将集合转化成只读的
				return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);	
			}
	
			//添加网络请求适配器
			public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
		      callAdapterFactories.add(checkNotNull(factory, "factory == null"));
		      return this;
		    }
		}
	}

看到callAdapterFactories存入开发者自行添加进去的网络请求适配器工厂,还存入该平台默认的网络请求适配器工厂,此处是Android平台,对应的网络请求适配器工厂为ExecutorCallAdapterFactory, 还记得我们在创建Retrofit时调用了.addCallAdapterFactory(RxJavaCallAdapterFactory.create()),所以此处自行添加的网络请求适配器工厂是RxJavaCallAdapterFactory.

现在也就找到callAdapterFactories是在Retrofit.Builder的build函数中存入适配器工厂的,存入了两个适配器工厂,分别是ExecutorCallAdapterFactory和RxJavaCallAdapterFactory.

那上面说的 “获取跟网络请求函数返回值Call<List< Contributor>>相关的网络请求适配器工厂”,获取到的就应该是ExecutorCallAdapterFactory和RxJavaCallAdapterFactory其中之一

在Retrofit类的nextCallAdapter函数中,通过遍历callAdapterFactories集合,取出网络请求适配器工厂并调用自身的get函数,我们看下ExecutorCallAdapterFactory和RxJavaCallAdapterFactory这两个类的get函数


	public final class RxJavaCallAdapterFactory extends CallAdapter.Factory {

	  @Override
	  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
	    Class<?> rawType = getRawType(returnType);
	    boolean isSingle = rawType == Single.class;
	    boolean isCompletable = rawType == Completable.class;

		//请求函数的返回值必须是 Observable或Single或Completable
    	//否则返回null
	    if (rawType != Observable.class && !isSingle && !isCompletable) {
	      return null;
	    }
	
	    if (isCompletable) {
	      return new RxJavaCallAdapter(Void.class, scheduler, isAsync, false, true, false, true);
	    }
	  }
	}

由于我们在上篇文章中写的网络请求函数的返回值是 “Call<List< Contributor>>”, 那RxJavaCallAdapterFactory的get函数中getRawType(returnType)拿到的Class类型就是Call,不满足判断条件, 所以此处会返回null, 因此不是RxJavaCallAdapterFactory


	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);
	    return new CallAdapter<Object, Call<?>>() {
	      @Override public Type responseType() {
	        return responseType;
	      }
	
	      //这里传入的call = OkHttpCall实例,callbackExecutor = MainThreadExecutor实例
	      @Override public Call<Object> adapt(Call<Object> call) {
	        return new ExecutorCallbackCall<>(callbackExecutor, call);
	      }
	    };
	  }
	}

ExecutorCallAdapterFactory类的get函数中,通过getRawType获取到的是Call类型,满足条件,那么满足适配器工厂条件的就是ExecutorCallAdapterFactory类,其get函数中创建了CallAdapter的匿名内部类并返回,那此处的匿名内部类实例就是ServiceMethod.Builder类的createCallAdapter函数中retrofit.callAdapter( )获取到的值,也就是在ServiceMethod.Builder类的build函数调用createCallAdapter函数返回的就是这个匿名内部类

2.ServiceMethod.Builder类的build函数,调用createResponseConverter函数是怎么生成responseConverter的?

这里生成的responseConverter的代码流程跟上面1类似

从createResponseConverter函数出发,调用到Retrofit类的nextResponseBodyConverter函数


	private Converter<ResponseBody, T> createResponseConverter() {
      Annotation[] annotations = method.getAnnotations();
      try {
        //遍历 存放数据转换器工厂的集合converterFactories,找到合适的数据转换器工厂并返回
        return retrofit.responseBodyConverter(responseType, annotations);
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(e, "Unable to create converter for %s", responseType);
      }
    }

	public final class Retrofit {

		 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");
		
		    //遍历 存放数据转换器工厂的集合converterFactories,找到合适的数据转换器工厂并返回
		    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);
		      if (converter != null) {
		        //noinspection unchecked
		        return (Converter<ResponseBody, T>) converter;
		      }
	   		}
			
				...省略无关代码
	   }
	}

在nextResponseBodyConverter函数中,主要遍历converterFactories这个存放数据转换器工厂的集合,获取跟网络请求函数返回值Call<List< Contributor>>相关的数据转换器工厂,那converterFactories在哪里存入数据转换器工厂? 存入了哪些数据转换器工厂?

converterFactories是在Retrofit的构造函数中赋值的, 而Retrofit是通过Build模式创建的, 看Retrofit.Builder类的build函数


	public final class Retrofit {
		public static final class Builder {

			public Retrofit build() {

			   //...省略无关代码
							
		      List<Converter.Factory> converterFactories =
		          new ArrayList<>(1 + this.converterFactories.size());
		
		      //将默认的数据转换器装载进工厂实例里,添加数据转换器工厂进集合里
		      converterFactories.add(new BuiltInConverters());
		      converterFactories.addAll(this.converterFactories);

			  //Collections.unmodifiableList()函数是将集合转化成只读的
           		return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);	
			
			}

			//添加数据转化器工厂
			public Builder addConverterFactory(Converter.Factory factory) {
		      converterFactories.add(checkNotNull(factory, "factory == null"));
		      return this;
		    }

		}
	}

看到converterFactories存入开发者自行添加进去的数据转换器工厂,还存入该平台默认的数据转换器工厂BuiltInConverters类的实例, 还记得我们在创建Retrofit时调用了.addConverterFactory(GsonConverterFactory.create()),所以此处自行添加的数据转换器工厂是GsonConverterFactory.

现在也就找到converterFactories是在Retrofit.Builder的build函数中存入转换器工厂的,存入了两个数据转换器工厂,分别是BuiltInConverters和GsonConverterFactory.

那上面说的 “获取跟网络请求函数返回值Call<List< Contributor>>相关的数据转换器工厂”,获取到的就应该是BuiltInConverters和GsonConverterFactory其中之一

在Retrofit类的nextResponseBodyConverter函数中,通过遍历converterFactories集合,取出数据转换器工厂并调用自身的responseBodyConverter函数,我们看下BuiltInConverters和GsonConverterFactory这两个类的responseBodyConverter函数


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

此处的type就是根据网络请求函数返回值Call<List< Contributor>> 获取到的响应数据类型,即type 等于java.util.List<com.example.retrofit.SimpleService$Contributor>,所以BuiltInConverters类的responseBodyConverter函数经过判断会返回null,显然不是这个系统默认的数据转换器工厂


	public final class GsonConverterFactory extends Converter.Factory {

		  @Override
		  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
		      Retrofit retrofit) {
		    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
		    return new GsonResponseBodyConverter<>(gson, adapter);
		  }
		
	}

根据type等于java.util.List<com.example.retrofit.SimpleService$Contributor>,返回的应该是GsonConverterFactory这个数据转换器工厂,在其responseBodyConverter函数中返回GsonResponseBodyConverter类的实例,GsonResponseBodyConverter是负责将响应数据转化为开发者指定的Java类

因此,在ServiceMethod.Builder类的build函数调用createResponseConverter函数返回的就是GsonResponseBodyConverter类的实例, 即responseConverter就是GsonResponseBodyConverter类的实例

3.OkHttpCall类的createRawCall函数中的call的具体实现类是哪个? 内部怎么实现的?


	final class OkHttpCall<T> implements Call<T> {

		private okhttp3.Call createRawCall() throws IOException {
		   
		    okhttp3.Call call = serviceMethod.toCall(args);
		    if (call == null) {
		      throw new NullPointerException("Call.Factory returned null.");
		    }
		    return call;
		}
	}

createRawCall函数中的call是通过调用ServiceMethod类的toCall函数生成的,看toCall函数


	final class ServiceMethod<R, T> {
		
		okhttp3.Call toCall(@Nullable Object... args) throws IOException {

		   	//...省略无关代码

		    //callFactory = OkHttpClient,该OkHttpClient是在Retrofit.Buidler的build函数中进行设置值的
		    //所以这里的okhttp3.Call来源于OkHttp.RealCall类的实例
		    return callFactory.newCall(requestBuilder.build());
		  }
	}

callFactory是在ServiceMethod的构造函数中被赋值,其值来自于Retrofit类,回到Retrofit.Builder类的build函数中


	public final class Retrofit {
		public static final class Builder {

			public Retrofit build() {
				//开发者是否传入OkHttpClient实例,未传入则创建
			      okhttp3.Call.Factory callFactory = this.callFactory;
			      if (callFactory == null) {
			        callFactory = new OkHttpClient();
			      }

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

			
			public Builder callFactory(okhttp3.Call.Factory factory) {
		      this.callFactory = checkNotNull(factory, "factory == null");
		      return this;
		    }
		}
	}

callFactory变量就是在此处被初始化的, 在创建Retrofit时,如果开发者未传入okhttp3.Call.Factory类的实现实例, 则会赋予系统默认的OkHttpClient,所以callFactory实际就是OkHttpClient实例.

接着回到ServiceMethod类的toCall函数,callFactory.newCall() 不就等于OkHttpClient.newCall(), 对OkHttp框架熟悉的话,是不是觉得似曾相似


	public class OkHttpClient implements Cloneable, Factory, okhttp3.WebSocket.Factory {

		public Call newCall(Request request) {
	        return RealCall.newRealCall(this, request, false);
	    }
	}

那么OkHttpCall类的createRawCall函数中的call也就是此处生成的RealCall实例. 从这可以看出,OkHttpCall类是通过OkHttp框架来发起异步/同步的请求

4.OkHttpCall类的enqueue函数和execute函数中调用的parseResponse(rawResponse)函数,内部是怎么解析响应数据的?


	final class OkHttpCall<T> implements Call<T> {

		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 {
	      //将响应数据转化为 网络请求函数中定义的返回类型
	      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;
	    }
	  }
	}

看上面的代码,核心在serviceMethod.toResponse这一句, 接着往下看


	final class ServiceMethod<R, T> {

		R toResponse(ResponseBody body) throws IOException {
		    return responseConverter.convert(body);
		}
	}

这里的responseConverter不就是上面第2个问题中获取到的GsonResponseBodyConverter类的实例,而GsonResponseBodyConverter内部是用了Gson框架来解析数据.


	final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
	  private final Gson gson;
	  private final TypeAdapter<T> adapter;
	
	  GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
	    this.gson = gson;
	    this.adapter = adapter;
	  }
	
	  @Override public T convert(ResponseBody value) throws IOException {
	    JsonReader jsonReader = gson.newJsonReader(value.charStream());
	    try {
	      T result = adapter.read(jsonReader);
	      if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
	        throw new JsonIOException("JSON document was not fully consumed.");
	      }
	      return result;
	    } finally {
	      value.close();
	    }
	  }
	}

5.retrofit类create函数中的serviceMethod.adapt是怎么返回OkHttpCall类的,内部是怎么实现的?


	public final class Retrofit {
		 public static final class Builder {

			public <T> T create(final Class<T> service) {

		    //检查网络请求接口类是不是接口,有没继承其他接口 等
		    Utils.validateServiceInterface(service);
		    //判断是否需要提前缓存ServiceMethod对象, validateEagerly默认为false
		    if (validateEagerly) {
		      eagerlyValidateMethods(service);
		    }
		    // 使用动态代理模式拿到 网络请求接口类的函数的注解、函数参数、函数返回值等相关信息
		    // 返回接口调用实例Call,其实这个Call是ExecutorCallbackCall类(Retrofit的Call的实现类)的实例,在后面的代码中能看到
		    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接口负责存 网络请求接口类的函数的注解、函数参数、函数返回值等相关信息
		              ServiceMethod<Object, Object> serviceMethod =
		                (ServiceMethod<Object, Object>) loadServiceMethod(method);
		            //OkHttpCall是对Retrofit.Call的实现,实际该类主要用到OkHttp.Call(rawCall这个变量) 来进行enqueue、execute请求
		            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
		            //这里实际上返回的是ExecutorCallbackCall类(Retrofit的Call的实现类)的实例,看后面的代码
		            return serviceMethod.adapt(okHttpCall);
		          }
		        });
		  }
		 }
	}

跟进去ServiceMethod类的adapt函数


	final class ServiceMethod<R, T> {
		T adapt(Call<R> call) {
	    	return callAdapter.adapt(call);
	    }
	}

adapt函数是调用了callAdapter对象的adapt函数,有没觉得这个callAdapter蛮熟悉的,这不就是上面第1点的callAdapter,它的值就是ExecutorCallAdapterFactory类中get函数中创建的匿名内部类


	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);
		    return new CallAdapter<Object, Call<?>>() {
		      @Override public Type responseType() {
		        return responseType;
		      }
		
		      //这里传入的call = OkHttpCall实例,callbackExecutor = MainThreadExecutor实例
		      @Override public Call<Object> adapt(Call<Object> call) {
		        return new ExecutorCallbackCall<>(callbackExecutor, call);
		      }
		    };
		  }
	}

那么retrofit类create函数中的serviceMethod.adapt()拿到的就是此处的ExecutorCallbackCall的实例,那ExecutorCallbackCall这个类又有什么用呢? 这里多提一个问题,ExecutorCallbackCall是Retrofit框架中很重要的一个类,往下看

6.从上面第5点知道retrofit类create函数中的serviceMethod.adapt()返回的是ExecutorCallbackCall类,这个类有什么作用?


	final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
		static final class ExecutorCallbackCall<T> implements Call<T> {

			final Executor callbackExecutor;
		    final Call<T> delegate;
		    //这里传入的delegate = OkHttpCall实例,callbackExecutor = MainThreadExecutor实例
		    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 = OkHttpCall实例
		      //OkHttpCall是对Retrofit.Call的实现,实际该类主要用到OkHttp.Call(rawCall这个变量) 来进行enqueue、execute请求
		      delegate.enqueue(new Callback<T>() {
		        @Override public void onResponse(Call<T> call, final Response<T> response) {
		          //callbackExecutor = MainThreadExecutor, 主要从子线程切换到主线程并返回响应结果
		          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 {
		      //这里的delegate = OkHttpCall实例
		      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();
		    }
		  
		}
	}

看上面的代码和注释,ExecutorCallAdapterFactory类主要做了两件事

  • 结合代码和注释,调用OkHttpCall类来发起请求,从上面第3点了解到,OkHttpCall类是通过OkHttp框架来发起异步/同步的请求,因此ExecutorCallbackCall类间接调用了OkHttp框架来发起异步/同步的请求

  • MainThreadExecutor把子线程切换到主线程, 将请求OkHttp框架返回的服务端响应数据回调返回

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
retrofit-spring-boot-starter是一个用于整合Retrofit库和Spring Boot的starter项目,它可以简化在Spring Boot中使用Retrofit的配置和使用。 以下是retrofit-spring-boot-starter的使用方法: 1. 在你的Spring Boot项目的pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>com.github.lianjiatech</groupId> <artifactId>retrofit-spring-boot-starter</artifactId> <version>1.0.0</version> </dependency> ``` 2. 创建一个接口,用于定义Retrofit的API接口。例如: ```java import retrofit2.http.GET; import retrofit2.http.Path; public interface MyApi { @GET("/users/{username}") User getUser(@Path("username") String username); } ``` 3. 在你的Spring Boot应用程序中,使用`@Autowired`注解将Retrofit的API接口注入到你的代码中。例如: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import retrofit2.Retrofit; @Service public class MyService { private final MyApi myApi; @Autowired public MyService(Retrofit retrofit) { this.myApi = retrofit.create(MyApi.class); } public User getUser(String username) { return myApi.getUser(username); } } ``` 4. 现在你可以在你的代码中使用`MyService`来调用Retrofit的API接口了。例如: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class MyController { private final MyService myService; @Autowired public MyController(MyService myService) { this.myService = myService; } @GetMapping("/users/{username}") public User getUser(@PathVariable String username) { return myService.getUser(username); } } ``` 以上是retrofit-spring-boot-starter的基本用法。你可以根据自己的需求进行配置和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值