代理网站源码分享,代理网址是什么

大家好,今天小编来为大家解答代理网站源码分享这个问题,代理网址是什么很多人还不知道,现在让我们一起来看看吧!

前言

关于动态代理的系列文章,到此便进入了最后的“一出好戏”。前俩篇内容分别展开了:从源码上,了解JDK实现动态代理的原理;以及从动态代理切入,学会看class文件结构的含义。

如果还没有看过这俩篇文章的小伙伴,可以看一看呦~(前俩篇是一个小伙伴总结的,这一篇由我来续上。至于他会不会结合动态代理捋一捋Java中的AOP,那就看他了,emmmmmm~~)

感兴趣的小伙伴可以关注我们,在历史文章中查看这俩篇内容。

[动态代理三部曲:中]-从动态代理,看Class文件结构定义]

[动态代理三部曲:上]-动态代理是如何”坑掉了”我4500块钱]

不扯这些没用的直接开整!

长文预警,建议收藏再看~

上源码

构建Retrofit对象

毫无疑问,分析源码要先从使用凡是入手。对于我们正常的Retrofit套路,我们会先构建一个接口,这里我们使用一个post请求(这个接口已经不能用了,很久没有倒腾我的服务器了~):

然后,我们会通过Builder构建一个Retrofit:

对于构建Retrofit来说,从外部看就是通过Builder模式去构建。但是细节之处,并非如此,让我们看一下baseUrl的内部实现。

内部很简单,通过builder.parase()的返回值来判断是否应该去调用build()方法。因此很明显,大量的逻辑是在parse()方法之中处理的。让我们进去一睹芳泽:

此方法内容非常的长,本质就是对url进行准确性的校验。这里我截取了一些较为关键的内容。

url构建之前有一个比较经典的校验过程:”baseUrlmustendin/:”+baseUrl。这个异常大家都不陌生吧?~baseUrl必须以/结尾。这里的过程,大家有兴趣可以自己看一下呦,原理是通过切割“/”字符串,来判断是不是以“/”结尾。这里切的url并非是咱们的baseUrl,而是构建完毕的url。因为篇幅原因,这里就不贴代码了。

动态代理部分

让我们进入下一个过程,动态代理开始的地方。构建了Retrofit对象直接,我们就开始生成我们的接口对象啦,点进入之后,我们就能看到,属于的动态代理的方法。还是熟悉的配方,熟悉的味道:

默认方法:是JDK1.8增加的接口中的内容。其关键字为default。(如果感兴趣这个新特性,小伙伴们可以自行了解~)

官网解释:如果此方法是默认方法,则返回true;否则返回false。默认方法:即在在接口类型中,声明的具有主体的非静态方法(有具体实现的)。(Returnstrueifthismethodisadefaultmethod;returnsfalseotherwise.Adefaultmethodisapublicnon-abstractinstancemethod,thatis,anon-staticmethodwithabody,declaredinaninterfacetype.)

俩种类型判断结束,让我们重点看一下:

ServiceMethod<Object,Object>serviceMethod=(ServiceMethod<Object,Object>)loadServiceMethod(method);这行代码做了什么。

我们点进去loadSerivceMethod()方法。

很明显,这里做了一次缓存。如果没有ServiceMethod对象,那么就通过Builder的方式去构建这个对象。那么Buidler的过程是什么样子的呢?

build()方法相对比较的长,这里我们看一些比较关键的地方。

关键点1:

拿到方法上的所有注解,然后遍历:

parseMethodAnnotation()方法:

parseHttpMethodAndPath()方法中,主要做了一件事情:通过传进来的注解对应的value去判断是否有?,如果有,那么?后边不能包含{}(通过正则表达式实现),否则抛异常。如果没有抛异常,那么通过正则切割{},存到一个Set之中,后续进行处理,也就是和参数中的Path注解的内容进行替换。(下文会涉及替换过程)

关键点2:

遍历过所有方法上的注解后,接下来就是参数注解了。

参数类型校验:

到达这里,第一步进行的操作,是判断参数类型。如果参数类型是TypeVariable(类型变量:T、V…)、WildcardType(通配符;?)则直接抛异常:

参数类型完毕后,便进入参数注解类型的判断。

参数注解类型校验:

正式校验参数注解类型的时候,会先判断是否有不含注解的参数,这里就会直接抛异常(也就是我们为什么不能在参数中传不用注解修饰参数报错的原因):

接下来便是校验参数注解类型。不过,这一部分实在没办法贴出来了,核心的判断方法大概有400行。为啥这么多?因为参数注解类型太多了,每一种都有自己的规则,所以判断内容很多。如果小伙伴有感兴趣的,可以自行去ServiceMethod类中的parseParameterAnnotation()方法查看。

请求接口Api类中,注解使用的异常。基本都是在这里处理的。如果小伙伴们遇到什么奇怪的异常,不妨不着急去百度/Google;让我们看看源码是怎么说的~~

Path替换{}的内容

这里我们解决一个疑问:那就是我们最开始处理url的时候,通过正则切割{},我们都知道,这里会通过Path注解去替换。那么这里就让我们看一看Retrofit是如何处理Path类型的注解的。

这里我们能看到,想进行接下来的操作。必然和Converter这个类有着密不可分的关系。

我们可以看到,第一次一定是没有Converter对象的。点进INSTANCE之后我们会发现这里构建了一个ToStringConverter类。初始化之后,再让我们回到Path类型中的判断里。最终我们会return一个“`returnnewParameterHandler.Path<>(name,converter,path.encoded());“`很明显这是一个内部类。其实它是一个封装类。对应封装了所有注解对应的java类。用于在请求网络的时候统一管理。而这个类只需要重写了apply方法。

当然,执行replace势必要引起apply方法的调用。很显然目前在动态代理的这个过程中,我们没有办法看到apply被调用。因此现在先按住不表,让我们先把动态代理部分整完。

newProxyInstance的return

我们上面看了,校验接口方法的参数类型/参数注解类型。这个逻辑过后,就是调用build,构建ServiceMethod。

构建完了ServiceMethod之后,让我们再把目光转移到Retrofit.create()中newProxyInstance的最后一点内容:

走到这,就通过动态代理构建出了我们接口方法中的Call对象。从这三行代码中,我们很明显看不出来猫腻,让我们走进OkHttpCall中:

这其中重写了Call中我们常用的方法,比如:enqueue()。内部是转发给okhttp3.Call(OkHttp)去处理真正的网络请求。

接下来让我们重点看一下return的“`serviceMethod.callAdapter.adapt(okHttpCall)“`方法。这里callAdapter的初始化就不展开,默认的是DefaultCallAdapterFactory:

这里我们因为没有设置适配的Adapter,比如:RxJava的。

看到这个类,我们就可以明确,这了返回的Call实际上就是我们动态代理中传递的OkHttpCall。

有了它,我们就可以执行我们想执行的网络请求的方法了。

那么此时我们就可以这么做了:

Call<ResponseBody>call=retrofitApi.postRetrofit(username,password);

call.enqueue(….)

动态代理部分接近尾声

走到这里,动态代理部分就结束了。不过我们还有一些问题没有看到结果。最简单的,上面所说的apply方式是谁调用的?其实这个问题很好解答。

我们通过上面的梳理,可以明确动态代理的部分仅仅是为了构建我们的接口类,而真正的调用并非在此。因此我们可以推断出apply的调用时机应该是正在去请求网络的时候。

因为本篇的主题是梳理Retrofit中动态代理的部分。所以关于真正请求的部分,就简单的进行总结下~见谅了,各位~

我们知道,我们正真请求网络是调用了Call中的方法:

那么Call的实现类是怎么被创建出来的呢?其中,上文我们已经看到,在newProxyInstance方法中return的时候,初始化的OkHttpCall。既然知道了Call的实现类是什么,那么我们就取其中比较有代表性的方法,来展开apply被调用的过程。

这里我们展开enqueue()方法做代表吧:

在这我们就很清晰的看到apply方法被调用~

总结

我们的Retrofit,通过动态代理,构建我们所需要的接口方法,其中校验我们的接口方法的注解,参数类型,参数注解类型;构建ServiceMethod对象,最终通过OkHttpCall,return出我们所需要的Call类型对象。

有了Call,我们就可以开始网络请求,当然网络请求的过程,在OkHttpCall中是被转发给OkHttp框架中的okhttp3.Call去执行的。

到此,从动态代理,看Retrofit的源码实现就结束了。这篇文章重点是去分析Retrofit中的动态代理的思路,所以在网络请求的源码过程并没有过多的涉猎。有机会的话,在Retrofit的源码实现中去总结吧。

在看源码的过程中,最大的感慨是框架设计上的巧妙。自己最近在重构公司的相机库,越来越感觉整体设计的重要性!唉,好难。

本文由IT面试填坑小分队原创,欢迎关注,带你一起长知识!

好了,本文到此结束,如果可以帮助到大家,还望关注本站哦!

Published by

风君子

独自遨游何稽首 揭天掀地慰生平