Android中的代理模式

代理的概念:为某个对象提供一个代理,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方均可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。 

 

 抽象对象角色:就是代理类和委托类共同的接口,声明了目标对象和代理对象的共同接口,这样一来在任何能够使用目标对象的地方均可以使用代理对象。 目标对象角色:就是委托类,定义了代理对象所表明的目标对象。 代理对象角色:就是代理类,代理对象内部含有目标对象的引用,从而能够在任什么时候候操做目标对象;代理对象提供一个与目标对象相同的接口,以即可以在任什么时候候替代目标对象。代理对象一般在客户端调用传递给目标对象以前或以后,执行某个操做,而不是单纯地将调用传递给目标对象。 静态代理 代理类在程序运行前已经存在的代理方式称为静态代理。 /** * 定义Demo接口 */
    public interface Demo { public void save(); } /** * DemoImpl实现Demo接口并覆写save()方法 * 真实主题,执行具体业务 */
    public class DemoImpl implements Demo { public void save() { System.out.println("调用save()方法"); } } /** * DemoImplProxy 也实现了Demo接口,并覆写了save()方法,增长了本身的业务 * 代理主题,负责其余业务的处理 */
    public class DemoImplProxy implements Demo { Demo demoImpl = new DemoImpl(); public void save() { System.out.println("开始记录日志"); demoImpl.save(); System.out.println("开始结束日志"); } } 静态代理有一个缺点,每一个代理类只能为一个接口服务,这样程序开发中必然会产生许多的代理类。 动态代理 代理类在程序运行前不存在、运行时由程序动态生成的代理方式称为动态代理。 实现动态代理包括三步: (1). 新建代理类和委托类共同的接口以及委托类; (2). 实现InvocationHandler接口,这是负责链接代理类和委托类的中间类必须实现的接口; (3). 经过Proxy类新建代理类对象。 第一步:新建代理类和委托类共同的接口以及委托类 public interface Operate { public void operateMethod1(); public void operateMethod2(); public void operateMethod3(); } public class OperateImpl implements Operate { @Override public void operateMethod1() { System.out.println("Invoke operateMethod1"); sleep(110); } @Override public void operateMethod2() { System.out.println("Invoke operateMethod2"); sleep(120); } @Override public void operateMethod3() { System.out.println("Invoke operateMethod3"); sleep(130); } private static void sleep(long millSeconds) { try { Thread.sleep(millSeconds); } catch (InterruptedException e) { e.printStackTrace(); } } } 第二步:实现InvocationHandler接口 java.lang.reflect.InvocationHandler接口的定义以下: /** * *Object proxy:被代理的对象 *Method method:要调用的方法 *Object[] args:方法调用时所须要参数 */
    public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; } 实现 InvocationHandler 接口 public class TimingInvocationHandler implements InvocationHandler { private Object target; public TimingInvocationHandler() {} public TimingInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long start = System.currentTimeMillis(); Object obj = method.invoke(target, args); System.out.println(method.getName() + " cost time is:" + (System.currentTimeMillis() - start)); return obj; } } 第三步:经过Proxy类新建代理类对象 java.lang.reflect.Proxy类的定义以下: /** *CLassLoader loader:类的加载器 *Class<?> interfaces:获得所有的接口 *InvocationHandler h:获得InvocationHandler接口的子类的实例 */
    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException public class Main { public static void main(String[] args) { // create proxy instance
            TimingInvocationHandler timingInvocationHandler = new TimingInvocationHandler(new OperateImpl()); Operate operate = (Operate)(Proxy.newProxyInstance(Operate.class.getClassLoader(), new Class[] {Operate.class}, timingInvocationHandler)); // call method of proxy instance
 operate.operateMethod1(); System.out.println(); operate.operateMethod2(); System.out.println(); operate.operateMethod3(); } } 下面总结一下动态代理对象建立过程 // InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发 // 其内部一般包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用
    InvocationHandler handler = new InvocationHandlerImpl(..); // 经过 Proxy 为包括 Interface 接口在内的一组接口动态建立代理类的类对象
    Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... }); // 经过反射从生成的类对象得到构造函数对象
    Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class }); // 经过构造函数对象建立动态代理类实例
    Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler }); 从上面能够看到,实际使用过程更加简单,由于 Proxy 的静态方法 newProxyInstance 已经为咱们封装了步骤 2 到步骤 4 的过程,因此简化后的过程以下 // InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
    InvocationHandler handler = new InvocationHandlerImpl(..); // 经过 Proxy 直接建立动态代理类实例
    Interface proxy = (Interface)Proxy.newProxyInstance( classLoader, new Class[] { Interface.class }, handler ); 参考文章: Java 动态代理机制分析 公共技术点之 Java 动态代理 代理模式和android插件化 Android设计模式源码解析之Proxy模式
相关文章
相关标签/搜索