Retrofit原理浅析
2017-12-15 10:26
381 查看
Retrofit是Square组织开发维护的一款网络框架。Retrofit非常适合处理RESTful风格的网络接口。Retrofit通过注解和动态代理简化了网络请求的代码工作量,与OKHttp为同一组织开发,能够很好的结合使用。
Retrofit和okhttp配合使用的优点
Retrofit其实是在okhttp的基础之上进行了封装。把网络请求都交给给了Okhttp,我们只需要通过简单的配置就能使用retrofit来进行网络请求了使得使用上更加简洁明了,并且配置灵活,能达到解耦的效果。
Retrofit非常巧妙的用注解来描述一个HTTP请求,将一个HTTP请求抽象成一个Java接口,然后用了Java动态代理的方式,动态的将这个接口的注解“翻译”成一个HTTP请求,最后OkHttp去发送这个HTTP请求。
Retrofit框架存在的优势:
① Retrofit使用注解方式,大大简化了我们的URL拼写形式,而且注解含义一目了然,简单易懂;
② Retrofit使用简单,结构层次分明,每一步都能清晰的表达出之所以要使用的寓意;
④ Retrofit支持同步和异步执行,使得请求变得异常简单,只要调用enqueue/execute即可完成;
④ Retrofit更大自由度的支持我们自定义的业务逻辑,如自定义Converters。
1. Retrofit介绍
一个用于android和Java平台的类型安全的网络框架。
Retrofit 是一个Square开发的类型安全的REST安卓客户端请求库。这个库为网络认证、API请求以及用OkHttp发送网络请求提供了强大的框架 。
Retrofit 把REST API返回的数据转化为Java对象,就像ORM框架那样,把数据库内的存储的数据转化为相应的Java bean对象。
那么我们知道Retrofit是一个类型安全的网络框架,而且它是使用REST API的,接下来我们看看什么是REST吧。
2. REST 介绍:资源表现层状态转化
Resources Representational State Transfer
资源表现层状态转化
2
3
4
类库原理解析
注解
Retrofit使用注解+java接口来定义后台服务API接口
注解主要分为 方法注解 和 参数注解
生成动态代理实例
Retrofit使用的关键一步就是Retrofit.create函数创建接口动态代理的示例,代码如下
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
可以看到是为接口的每个method创建了一个对应的ServiceMethod,并使用这个ServiceMethod对象创建OkHttpCall,并使用ServiceMethod实例的callAdapter来调用okhttpCall并返回结果。
调用流程
通过上面代码可以看到调用关键的就是三步:
加载对应method的ServiceMethod实例
使用ServiceMethod实例和方法调用参数创建OkHttpCall
调用serviceMethod.callAdapter.adapt(okHttpCall)来产生method所定义的返回(Call或者其他自定义CallAdapter支持的返回)
第一步、加载对应method的ServiceMethod实例
ServiceMethod中有以下四个变量比较重要
2
3
4
callFactory是用来创建真正要执行的okhttp3.Call的工厂类,可以Retrofit.Builder中设置,如果不设置,默认会new一个OkHttpClient作为callFactory
callAdapter是用来最终处理OkHttpCall实例并返回接口Method所定义的返回
responseConverter 用来将Http请求的结果转换成接口Method所定义的结果(return或者Callback中的T)
parameterHandlers 根据接口Method参数的注解所生成的参数处理Handler数组
然后我们来看Retrofit.loadServiceMethod方法
2
3
4
5
6
7
8
9
10
11
可以看到此处先检查serviceMethodCache是否有该method对应的ServiceMethod实例缓存,如果没有,则创建一个该method对应的ServiceMethod实例并保存到缓存中。
ServiceMethod的创建使用的是建造者模式。
在ServiceMethod.Builder的build方法中,通过解析传入的method的方法定义(参数类型,返回类型,参数注解,方法注解)生成对应的callAdapter,responseConverter,parameterHandlers及其他一些创建请求需要用到的信息。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
此处在ServiceMethod.Builder.build()过程在生成过程中还会对method的定义做合法性检查,如:http方法是get就不允许方法参数中有body类型的参数;方法为post则必须有参数为Body类型。
第二步、使用ServiceMethod实例和方法调用参数创建OkHttpCall
获取到method对应的ServiceMethod实例后,会使用该ServiceMethod实例和方法调用的参数Object… args生成一个OkHttpCall。而OkHttpCall实际上是okhttp3.Call的一个包装类,实际调用OkHttpCall的相关执行方法时最终是调用OkHttpCall内部用ServiceMethod.callFactory创建的okhttp3.Call来执行网络请求。
第三步、调用serviceMethod.callAdapter.adapt(okHttpCall)来产生method所定义的返回
Retrofit2默认支持的返回是返回一个Call,利用此Call实例可执行
或
2
3
4
5
6
7
8
9
简单总结一下Retrofit的主要内部实现:
1.Retrofit实例的构造,填充一些参数,比如将在后面谈到的callAdapterFactory、convertFactory,以及baseUrl,callFactory(与callAdapterFactory作区分,若不指定,则为一个默认的OkHttpClient,可以根据需要创建一个OkHttpClient,然后对这个OkHttpClient添加对应的属性,以实现不同的网络处理机制)。
2.Retrofit调用create创建一个代理实体,而代理关键部分在于创建一个ServiceMethod,ServiceMethod收集接口方法的参数类型以及对应的注解,组成一个有关网络请求的参数类型集合。
3.ServiceMethod与接口方法传入的参数共同作用传入OkHttpCall,构成一个Call对象,经过CallAdapterFactory的适配,返回。因此接口方法可以理解为最后获得这个Call对象(真实来说应该是OkHttpCall)。
4.Call对象调用enqueue实际使用的是OkHttp的RealCall的enqueue方法,因此Retrofit的Call对象可以看成是OkHttp的Call的一个封装。当然,这不是一个简单的封装,在网络请求获得响应后,OkHttpCall还会对返回的信息进行转置,根据ConvertFactory定义的转置模式进行转换。
Retrofit和okhttp配合使用的优点
Retrofit其实是在okhttp的基础之上进行了封装。把网络请求都交给给了Okhttp,我们只需要通过简单的配置就能使用retrofit来进行网络请求了使得使用上更加简洁明了,并且配置灵活,能达到解耦的效果。
Retrofit非常巧妙的用注解来描述一个HTTP请求,将一个HTTP请求抽象成一个Java接口,然后用了Java动态代理的方式,动态的将这个接口的注解“翻译”成一个HTTP请求,最后OkHttp去发送这个HTTP请求。
Retrofit框架存在的优势:
① Retrofit使用注解方式,大大简化了我们的URL拼写形式,而且注解含义一目了然,简单易懂;
② Retrofit使用简单,结构层次分明,每一步都能清晰的表达出之所以要使用的寓意;
④ Retrofit支持同步和异步执行,使得请求变得异常简单,只要调用enqueue/execute即可完成;
④ Retrofit更大自由度的支持我们自定义的业务逻辑,如自定义Converters。
1. Retrofit介绍
一个用于android和Java平台的类型安全的网络框架。
Retrofit 是一个Square开发的类型安全的REST安卓客户端请求库。这个库为网络认证、API请求以及用OkHttp发送网络请求提供了强大的框架 。
Retrofit 把REST API返回的数据转化为Java对象,就像ORM框架那样,把数据库内的存储的数据转化为相应的Java bean对象。
那么我们知道Retrofit是一个类型安全的网络框架,而且它是使用REST API的,接下来我们看看什么是REST吧。
2. REST 介绍:资源表现层状态转化
Resources Representational State Transfer
资源表现层状态转化
1.每一个URI代表一种资源 2.客户端和服务器之间,传递这种资源的某种 表现层(“资源”具体呈现出来的形式,比如.txt,.png,.jpg) 3.客户端通过四个HTTP动词(GET用来获取资源,POST用来新建或更新资源,PUT用来更新资源,DELETE 用来删除资源)对服务器端资源进行操作,实现”表现层状态转化”1
2
3
4
类库原理解析
注解
Retrofit使用注解+java接口来定义后台服务API接口
注解主要分为 方法注解 和 参数注解
生成动态代理实例
Retrofit使用的关键一步就是Retrofit.create函数创建接口动态代理的示例,代码如下
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety. 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, 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 = loadServiceMethod(method); OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall); } }); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
可以看到是为接口的每个method创建了一个对应的ServiceMethod,并使用这个ServiceMethod对象创建OkHttpCall,并使用ServiceMethod实例的callAdapter来调用okhttpCall并返回结果。
调用流程
通过上面代码可以看到调用关键的就是三步:
加载对应method的ServiceMethod实例
使用ServiceMethod实例和方法调用参数创建OkHttpCall
调用serviceMethod.callAdapter.adapt(okHttpCall)来产生method所定义的返回(Call或者其他自定义CallAdapter支持的返回)
第一步、加载对应method的ServiceMethod实例
ServiceMethod中有以下四个变量比较重要
final okhttp3.Call.Factory callFactory; final CallAdapter<?> callAdapter; private final Converter<ResponseBody, T> responseConverter; private final ParameterHandler<?>[] parameterHandlers;1
2
3
4
callFactory是用来创建真正要执行的okhttp3.Call的工厂类,可以Retrofit.Builder中设置,如果不设置,默认会new一个OkHttpClient作为callFactory
callAdapter是用来最终处理OkHttpCall实例并返回接口Method所定义的返回
responseConverter 用来将Http请求的结果转换成接口Method所定义的结果(return或者Callback中的T)
parameterHandlers 根据接口Method参数的注解所生成的参数处理Handler数组
然后我们来看Retrofit.loadServiceMethod方法
ServiceMethod loadServiceMethod(Method method) { ServiceMethod result; synchronized (serviceMethodCache) { result = serviceMethodCache.get(method); if (result == null) { result = new ServiceMethod.Builder(this, method).build(); serviceMethodCache.put(method, result); } } return result; }1
2
3
4
5
6
7
8
9
10
11
可以看到此处先检查serviceMethodCache是否有该method对应的ServiceMethod实例缓存,如果没有,则创建一个该method对应的ServiceMethod实例并保存到缓存中。
ServiceMethod的创建使用的是建造者模式。
在ServiceMethod.Builder的build方法中,通过解析传入的method的方法定义(参数类型,返回类型,参数注解,方法注解)生成对应的callAdapter,responseConverter,parameterHandlers及其他一些创建请求需要用到的信息。
public ServiceMethod build() { callAdapter = createCallAdapter(); ......检查返回结果类型...... responseConverter = createResponseConverter(); //生成方法注解的处理器 for (Annotation annotation : methodAnnotations) { parseMethodAnnotation(annotation); } .....方法与注解合法性检查..... int parameterCount = parameterAnnotationsArray.length; parameterHandlers = new ParameterHandler<?>[parameterCount]; for (int p = 0; p < parameterCount; p++) { .....注解合法性检查.... parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations); } ......方法与注解合法性检查...... return new ServiceMethod<>(this); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
此处在ServiceMethod.Builder.build()过程在生成过程中还会对method的定义做合法性检查,如:http方法是get就不允许方法参数中有body类型的参数;方法为post则必须有参数为Body类型。
第二步、使用ServiceMethod实例和方法调用参数创建OkHttpCall
获取到method对应的ServiceMethod实例后,会使用该ServiceMethod实例和方法调用的参数Object… args生成一个OkHttpCall。而OkHttpCall实际上是okhttp3.Call的一个包装类,实际调用OkHttpCall的相关执行方法时最终是调用OkHttpCall内部用ServiceMethod.callFactory创建的okhttp3.Call来执行网络请求。
第三步、调用serviceMethod.callAdapter.adapt(okHttpCall)来产生method所定义的返回
Retrofit2默认支持的返回是返回一个Call,利用此Call实例可执行
Response<T> result = call.execute();//同步执行1
或
//异步执行 call.enqueue(new Callback(){ public void onResponse(Call<T> call, Response<T> response){ //TODO } public void onFailure(Call<T> call, Throwable t){ //TODO } });1
2
3
4
5
6
7
8
9
简单总结一下Retrofit的主要内部实现:
1.Retrofit实例的构造,填充一些参数,比如将在后面谈到的callAdapterFactory、convertFactory,以及baseUrl,callFactory(与callAdapterFactory作区分,若不指定,则为一个默认的OkHttpClient,可以根据需要创建一个OkHttpClient,然后对这个OkHttpClient添加对应的属性,以实现不同的网络处理机制)。
2.Retrofit调用create创建一个代理实体,而代理关键部分在于创建一个ServiceMethod,ServiceMethod收集接口方法的参数类型以及对应的注解,组成一个有关网络请求的参数类型集合。
3.ServiceMethod与接口方法传入的参数共同作用传入OkHttpCall,构成一个Call对象,经过CallAdapterFactory的适配,返回。因此接口方法可以理解为最后获得这个Call对象(真实来说应该是OkHttpCall)。
4.Call对象调用enqueue实际使用的是OkHttp的RealCall的enqueue方法,因此Retrofit的Call对象可以看成是OkHttp的Call的一个封装。当然,这不是一个简单的封装,在网络请求获得响应后,OkHttpCall还会对返回的信息进行转置,根据ConvertFactory定义的转置模式进行转换。
相关文章推荐
- Retrofit原理浅析
- Retrofit原理浅析
- Spring mvc 原理浅析
- JAVA EJB原理浅析
- Android中ListView原理与优化 浅析
- localtunnel.me 原理流程浅析
- 使用CTS进行漏洞检测及原理浅析
- Windows内核调试器原理浅析
- SpringMVC原理浅析
- Visual Studio Async CTP的实现原理浅析 - 跳出Task,构建自己的Awaiter
- Netty实现原理浅析
- 哈希表的原理个人理解与浅析
- .NET垃圾回收器(GC)原理浅析
- LeakCanary核心原理源码浅析
- 浅析Android字体加载原理
- Netty实现原理浅析
- Netty实现原理浅析
- Android框架浅析之锁屏(Keyguard)机制原理(转)
- 有关搜索引擎爬虫抓取原理浅析
- malloc分配原理浅析 mmap关注焦点 如何优化分配内存