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 create(final Class 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 serviceMethod =
                (ServiceMethod) loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  } 
  

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

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

四,代理模式的好处?

谈谈您的看法

你可能感兴趣的:(Android笔记,java,proxy,代理模式,retrofit)