Retrofit源码学习二:代理模式

目录

系列文章:

代理模式简介:

静态代理:

动态代理:

InvocationHandler:

代码实现:

动态代理总结:


系列文章:

Retrofit源码学习一:Retrofit介绍

Retrofit源码学习二:代理模式

Retrofit源码学习三:Retrofit源码详解一

Retrofit源码学习四:Retrofit源码详解二

Retrofit源码学习五:Retrofit中同步、异步请求解析

Retrofit源码学习六:框架中的设计模式

代理模式简介:

代理模式:为其他对象提供一种代理,用以控制对这个对象的访问。如下图所示:

静态代理:

/**
 * Description:抽象对象
 */
public abstract class AbstractObject {
    protected abstract void operation();
}

/**
 * Description:目标对象
 */
public class RealObject extends AbstractObject {
    @Override
    protected void operation() {
        System.out.println("do operation...");
    }
}

/**
 * Description:代理类
 */
public class ProxyObject extends AbstractObject {
    //对目标类的引用
    private RealObject realObject;

    public ProxyObject(RealObject realObject) {
        this.realObject = realObject;
    }

    @Override
    protected void operation() {
        System.out.println("do something before real operation...");
        if (realObject == null) {
            realObject = new RealObject();
        }
        realObject.operation();
        System.out.println("do something after real operation...");
    }
}

动态代理:

动态代理模式是Retrofit中一种非常重要的设计模式。也是Java中非常重要的一种特性。

特点:无侵入地增强我们的方法(在不用修改原来的代码的前提下,在已有的方法的前后,做我们想做的事情)。

定义:代理类在程序运行时创建的代理方式。也就是说,在这种动态代理模式下,代理类并不是在java代码中定义的,而是在运行时根据我们在java代码中的配置动态生成的。

相比于静态代理,动态代理的一个很大优点就是它能很方便地对我们的代理的函数进行统一处理,而不用频繁地修改每一个代理类的函数。

现在,只有两种动态代理的写法:

1、jdk动态搭理。需要客户端写辅助接口来实现。由java的内部的反射机制来实现,所以说它在生成类的过程中是比较高效的,我们主要讲的就是这种写法。主要注意的是,它只能为接口创建动态代理。

2、CGLIB动态代理。可以直接修改字节码。

InvocationHandler:

  • 每个代理类的对象都会关联一个表示内部处理逻辑的InvocationHandler接口的实现
  • invoke方法的参数中可以获取参数
  • invoke方法的返回值被返回给使用者

代码实现:

public interface Subject {
    void shopping();
}

public class Man implements Subject {
    @Override
    public void shopping() {
        System.out.println("xxx" + "要去买东西...");
    }
}

public class Proxy implements InvocationHandler {

    //要代理的真实对象
    private Object target;

    public Proxy(Subject target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("proxy: " + proxy.getClass().getName());
        System.out.println("before...");
        method.invoke(target, args);
        System.out.println("after...");
        return null;
    }

}

public class Client {

    public static void main(String[] args) {
        Subject man = new Man();
        Proxy p = new Proxy(man);
        //通过java.lang.reflect.newProxyInstance(...)方法获得真实对象的代理对象
        Subject subject= (Subject) java.lang.reflect.Proxy.newProxyInstance(
                man.getClass().getClassLoader(), man.getClass().getInterfaces(),p);
        //通过代理对象调用真实对象相关接口中实现的方法,这个时候就会跳转到这个代理对象所关联的handler的invoke()方法
        subject.shopping();
        //获得真实对象的代理对象所对应的Class对象的名称,用字符串表示
        System.out.println(subject.getClass().getName());
    }

}

动态代理总结:

  • 运行期
  • InvocationHandler接口和Proxy类
  • 动态代理与静态代理最大的不同就是:动态代理的代理类是不需要我们手动生成的,是在运行时动态生成的
     

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值