Retrofit2.X解析(一)Retrofit基本使用以及动态代理

Retrofit基本使用

参考官方文档:https://square.github.io/retrofit/
马老师教导我们要穿一手鞋,而且官方文档足够的详细。

代理模式

在我们使用 Retrofit 进行网络请求时,实际其内部使用 OkHttp 来完成网络请求的,然后,使用我们传入的 “类型转换器” 把响应转换成我们指定的类型。定义了一个接口并调用了该接口的方法,然后就拿到了请求的结果,这看上去非常简洁,而这其中的最功不可没的就是动态代理。

代理模式也叫委托模式,是结构型设计模式的一种。在Android中代理模式有很多,如Binder。生活中也有很多代理的例子,例如代购、看国外的风景等。
代理模式结构图:
在这里插入图片描述

  • Client:客户端类。
  • Subject:抽象主题类,用于声明真实主题与代理的共同接口方法。
  • RealSubject:真实主题类,定义了代理所表示的真实对象,客户端通过代理类间接的调用真实主题类的方法。
  • ProxySubject:代理类,抽象主题类的实现类。并持有对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行。

代理模式的简单实现

假设我想看看qiang外的风景,但是门被焊死了,焊门的兄弟临走连窗户也给堵上了,这个时候我就需要一个梯子(因为我不够高)

抽象主题类(Subject)

抽象主题类具有真实主题类和代理的共同接口方法,我想看风景,那么共同的方法就是看风景:

public interface ILadder {
    /**
     * 看风景
     */
    void climbWall();
}

真实主题类(RealSubject)

为了能看到腐国的自由女神像,所以搞一个腐国的梯子(AmericaLadder),它还得有看风景的能力:

public class AmericaLadder implements ILadder {
    @Override
    public void climbWall() {
        System.out.print("我看到了自由女神像");
    }
}

代理类(ProxySubject)

梯子并不是我的,是我的一个朋友提供给我的,所以我是通过我的朋友得到的这个梯子实现的看风景的能力:

public class MyFriendProxy implements ILadder {
    /**
     * 朋友的梯子
     */
    private ILadder iLadder;

    public MyFriendProxy(ILadder iLadder){
        this.iLadder=iLadder;
    }
    @Override
    public void climbWall() {
        iLadder.climbWall();
    }
}

客户端类(Client)

有了梯子,才能看到外面的风景。

public class Client {
    public static void main(String[] args) {
        //创建AmericaLadder
        ILadder americaLadder=new AmericaLadder();
        //创建代理并将AmericaLadder作为构造函数传
        ILadder myFriend=new MyFriendProxy(americaLadder);
        //看风景了
        myFriend.climbWall();
    }
}

运行结果:
在这里插入图片描述

动态代理的简单实现

从编码的角度来说,代理模式分为静态代理和动态代理,上面的例子是静态代理,在代码运行前就已经存在了代理类的class编译文件,而动态代理则是在代码运行时通过反射来动态的生成代理类的对象,并确定到底来代理谁。也就是我们在编码阶段不需要知道代理谁,代理谁我们将会在代码运行时决定。

为什么要使用动态代理?

因为一个静态代理类只能服务一种类型的目标对象,在目标对象较多的情况下,会出现代理类较多、代码量较大的问题。想象一下如果想在其他国家的风景,还得创建其他国家的梯子,世界上有197个国家(特朗普说有184……),这是多么浩大的工程……
Java提供了动态的代理接口InvocationHandler,实现该接口需要重写invoke()方法。
因此看风景动态代理类如下:

public class DynamicAmercaLadder implements InvocationHandler {

    private Object obj;
    public DynamicAmercaLadder(Object obj){
        this.obj=obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result=method.invoke(obj, args);
        return result;
    }
}

客户端实现如下:

public class Client {
    private static void climbWall(ILadder iLadder){
        //创建代理并将AmericaLadder作为构造函数传
        DynamicAmercaLadder dynamicAmercaLadder = new DynamicAmercaLadder(iLadder);
        //创建AmericaLadder的ClassLoader
        ClassLoader loader = iLadder.getClass().getClassLoader();
        //动态创建代理类
        ILadder myFriend= (ILadder) Proxy.newProxyInstance(loader,new Class[]{ILadder.class},dynamicAmercaLadder);
        //看风景了
        myFriend.climbWall();
    }

    public static void main(String[] args) {
        //创建AmericaLadder
        ILadder americaLadder = new AmericaLadder();
        climbWall(americaLadder);
        //创建EnglandLadder
        ILadder englandLadder = new EnglandLadder();
        climbWall(englandLadder);
    }
}

其中EnglandLadder:

public class EnglandLadder implements ILadder {
    @Override
    public void climbWall() {
        System.out.println("我看到了大本钟");
    }
}

从上面可以看出如果用静态代理,看美国的自由女神跟英国的大本钟我必须要分别创建对应的代理类,但是用动态代理,无论是看哪的风景只需要一个DynamicAmercaLadder就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章