阅读 286

Android小知识-剖析Retrofit前的预备知识(静态代理与动态代理)

本平台的文章更新会有延迟,大家可以关注微信公众号-顾林海,包括年底前会更新kotlin由浅入深系列教程,目前计划在微信公众号进行首发,如果大家想获取最新教程,请关注微信公众号,谢谢!

代理设计模式主要分为静态代理与动态代理,代理模式的定义是为其他对象提供一种代理,用以控制对这个对象的访问。打个比方:你人在国内,但是想要购买国外的某件商品,这时候你可以找朋友帮你买,你朋友就是代理,至于你朋友怎么买你不关心,你只要拿到商品就行。

静态代理

image

看上面这张类图,静态代理需要三个角色,一个是抽象对象角色(AbstractObject),一个是目标对象角色(RealObject),最后是代理对象角色(ProxyObject),在抽象对象角色类中定义了目标对象和代理对象的共同接口,RealObject是代理对象所代理的目标对象,ProxyObject是代理对象角色,内部会持有目标对象角色的引用,这样的话可以通过代理对象执行目标对象内的方法,接下来看具体的代码实现。

抽象对象角色:

public abstract class AbstractObject {
    protected abstract void operation();
}
复制代码

目标对象角色:

public class RealObject extends AbstractObject {
    @Override
    protected void operation() {
        System.out.println("目标对象的方法");
    }
}
复制代码

代理对象角色:

public class ProxyObject extends AbstractObject {

    private AbstractObject mRealObject;

    public ProxyObject(AbstractObject realObject){
        this.mRealObject=realObject;
    }

    @Override
    protected void operation() {
        System.out.println("执行目标对象前的工作....");
        this.mRealObject.operation();
        System.out.println("执行目标对象后的工作....");
    }
}
复制代码

在代理对象的operation方法中我们可以进行一些额外的操作,比如日志的统计或者业务逻辑处理等。在日常开发中对已有的代码做改进,这时可以使用一个代理类对原有的结果进行控制。

动态代理

在Retrofit中使用到了动态代理,使用动态代理,可以无侵入式的扩展代码,在不改动原有代码的情况下,增强一些方法或功能,它的定义是:在程序运行时创建的代理方式。

接下来通过一个实例来了解动态代理:

public interface Subject {
    void operation();
}
复制代码

创建了一个Subject接口,它是代理类和被代理类共同实现的一个接口。

public class RealObject implements Subject {
    @Override
    public void operation() {
        System.out.println("目标对象的方法");
    }
}
复制代码

RealObject是被代理对象,内部operation方法执行被代理类原有的方法。

public class ProxyObject implements InvocationHandler {

    private Object mRealObject;

    public ProxyObject(Object realObject){
        this.mRealObject=realObject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if("operation".equals(method.getName())){
            System.out.println("哈哈,捕捉到operation方法,我要做点其他事情...");
            return  method.invoke(mRealObject,args);
        }
        return null;
    }
}
复制代码

ProxyObject就是代理类,mRealObject代表真实的对象,ProxyObject需要实现InvocationHandler接口,并实现invoke方法,方法内部第一个参数proxy表示被代理的真实对象,第二个参数method表示真实对象的方法,第三个参数args表示真实对象的方法的参数。

public class Test {
    public static void main(String[] args) {
        Subject subject=new RealObject();
        Subject proxyObject= (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(),
                new Class<?>[]{Subject.class},
                new ProxyObject(subject));
        proxyObject.operation();
    }
}
复制代码

通过Proxy的newProxyInstance方法创建代理类,传入第一个参数是被代理类的ClassLoader,第二个参数是被代理实现的接口,第三个参数就是实现了InvocationHandler的对象。

执行结果:

哈哈,捕捉到operation方法,我要做点其他事情...
目标对象的方法
复制代码

在代理类ProxyObject的invoke方法中拦截到了operation方法,这时可以添加上我们需要的代码或功能。


838794-506ddad529df4cd4.webp.jpg

搜索微信“顾林海”公众号,定期推送优质文章。

关注下面的标签,发现更多相似文章
评论