美文网首页Android开发Android文章Android开发
Android小知识-剖析Retrofit前的预备知识(静态代理

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

作者: 爱读书的顾先生 | 来源:发表于2018-10-31 18:56 被阅读140次

    本平台的文章更新会有延迟,大家可以关注微信公众号-顾林海,包括年底前会更新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

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

    相关文章

      网友评论

        本文标题:Android小知识-剖析Retrofit前的预备知识(静态代理

        本文链接:https://www.haomeiwen.com/subject/zlqztqtx.html