Android中动态代理模式的应用

欲理解动态代理,可能先了解静态代理更容易理解.

一,静态代理

从静态代理UML图可以看到,主要有三个角色:共同接口,代理对象和被代理对象(真实对象),代理对象和真实对象都继承自共同的接口.同时,代理对象拥有真实对象的引用.

//共同的接口
public interface Subject {
    void operate1();
    void operate2(String str);
}

//被代理对象(真实对象)
public class RealSubject implements Subject {
    @Override
    public void operate1() {
        System.out.println("this is operate1");
    }

    @Override
    public void operate2(String str) {
        System.out.println("this is operate2 with args: "+str);
    }
}

//代理对象
public class ProxySubject implements Subject {
    private Subject realSubject; //此处应为接口--面向接口

    public ProxySubject(Subject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public void operate1() {
        //代理对象将方法调用转发给真实对象
        realSubject.operate1();
    }

    @Override
    public void operate2(String str) {
        realSubject.operate2(str);
    }
}

//客户类
public class ProxyClient {
    public static void main(String[] args) {
        Subject realSubject = new RealSubject();
        ProxySubject proxySubject = new ProxySubject(realSubject);
        //表面上是代理类操作自己的方法,实际上是将方法调用转发给了真实对象
        proxySubject.operate1();              
    }
}

二,动态代理

所谓静态和动态指的是,接口方法的调用方式.静态代理,是真实对象显式地方法调用,而动态代理则是通过反射的方式调用真实对象的方法.

public class DynamicProxy implements InvocationHandler {
    // 这个就是我们要代理的真实对象
    private Object subject;

    // 构造方法,给我们要代理的真实对象赋初值
    public DynamicProxy(Object subject) {
        this.subject = subject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(subject, args);
    }
}

public class ProxyClient {
    public static void main(String[] args) {
        Subject realSubject = new RealSubject();

        InvocationHandler handler = new design.pattern.structure.proxy.demo.DynamicProxy(realSubject);
        Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler);
        subject.operate1();
        subject.operate2("hello proxy");
    }
}

三大角色:接口类,真实对象,InvocationHandler的实现类 

通过Java的Proxy.newProxyInstance的方法调用,给Subject生成了一个实例对象;接口方法的调用,会传递给handler中,handler通过invoke的执行,间接地调用了真实对象的方法.

三,安卓中的应用

很典型的一个动态代理应用是Retrofit框架

public <T> T create(final Class<T> service) {
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

这是为Service任一个接口方法创建一个Call,用这个Call代表Http请求.

GitHub github = retrofit.create(GitHub.class);
Call<List<Contributor>> call = github.contributors("square", "retrofit");

四,代理模式的好处?

谈谈您的看法

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值