We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A type-safe HTTP client for Android and Java
基于 version 2.5.0 进行分析。
官方使用文档
Retrofit 将 Http API 转换为 java 接口,因此可以做如下定义
public interface GitHubService { // 请求方法和地址 @GET("users/{user}/repos") // 参数和返回值定义 Call<List<Repo>> listRepos(@Path("user") String user); }
生成 上述接口的实现类。
// 实例化 retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com/") .build(); // 创建接口实现 GitHubService service = retrofit.create(GitHubService.class);
发起异步请求,之后交给 okhttp 来做底层处理,回到之前对 okhttp 请求过程的分析。
Call<List<Repo>> repos = service.listRepos("octocat");
下面就针对每一部分进行源码分析。
首先对 retrofit 实例的创建,用的是建造者模式。这里直接看最后的 build() 过程,直接了解配置了什么参数。
public Retrofit build() { if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } // okhttp call 创建工厂,工厂模式的体现。 // 将类实例化操作和使用对像的操作分开 okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { // okhttp 对象,用于创建 call 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. // call 调用适配器,使得返回接口定义的返回值 List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories); callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor)); // Make a defensive copy of the converters. // 序列和反序列化转换器 List<Converter.Factory> 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); }
接着就可以实现之前声明的接口。
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety. // 最重要的部分 public <T> T create(final Class<T> service) { // 判断是接口并且不能继承其他接口 Utils.validateServiceInterface(service); if (validateEagerly) { // 提前对 service 中的方法注解进行合法性验证 eagerlyValidateMethods(service); } // 使用动态代理生成对应的 Service return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, // 处理被代理对象的某个方法发生是调用,比如这里的 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 并返回正在使用的方法 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; }
在上面的过程中,代理类解析方法的相关注解,包括 http 的请求方法, 地址,参数等信息,内容比较多,可以深入去看。下面就到了请求过程。
上次还提到动态代理, 当 service.listRepos("octocat") 时,接口中的调用会集中转发到 InvocationHandler 的 invoke() 方法,集中进行处理。
当发生方法调用时,请求过程会来到如下代码:
@Override final @Nullable ReturnT invoke(Object[] args) { Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter); return adapt(call, args); }
用相关的信息创建一个 okhttp 的 call 对象,
追下去就是 okhttp 的请求过程了。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Retrofit
基于 version 2.5.0 进行分析。
Demo
官方使用文档
Retrofit 将 Http API 转换为 java 接口,因此可以做如下定义
生成 上述接口的实现类。
发起异步请求,之后交给 okhttp 来做底层处理,回到之前对 okhttp 请求过程的分析。
下面就针对每一部分进行源码分析。
Retrofit
首先对 retrofit 实例的创建,用的是建造者模式。这里直接看最后的 build() 过程,直接了解配置了什么参数。
interface
接着就可以实现之前声明的接口。
在上面的过程中,代理类解析方法的相关注解,包括 http 的请求方法, 地址,参数等信息,内容比较多,可以深入去看。下面就到了请求过程。
上次还提到动态代理, 当 service.listRepos("octocat") 时,接口中的调用会集中转发到 InvocationHandler 的 invoke() 方法,集中进行处理。
请求过程
当发生方法调用时,请求过程会来到如下代码:
用相关的信息创建一个 okhttp 的 call 对象,
追下去就是 okhttp 的请求过程了。
The text was updated successfully, but these errors were encountered: