Android中使用Java的动态代理

同事写一个功能的时候,使用了Java的动态代理,虽然我不赞同他在实现那个功能时使用这项技术,但是不能忽略动态代理在Android中的作用的。
比如很多插件化框架就是以动态代理为原理的。Android插件化原理解析——Hook机制之动态代理
所以这里简单介绍下java代理相关的知识。
1.Java的代理模式

【Android中使用Java的动态代理】定义:为其他对象提供一种代理以控制对这个对象的访问
说白了就是在一个对象不好修改时,可以通过new一个新的代理对象对他进行控制,并且可以很容易的加入一些新的方法和特性。
Java的代理技术一般分为三种,静态代理、动态代理及Cglib代理。
2.静态代理 静态代理比较简单,看下下面的代码就很好理解了。
//定义一个接口 public interface Interface { void doSomething(); void somethingElse(String args); }

//定义一个被代理的类 public class RealObject implements Interface {@Override public void doSomething() { System.out.println("doSomething"); }@Override public void somethingElse(String args) { System.out.println("somethingElse" + args); } }

//新的代理的类 public class SimpleProxy implements Interface { //被代理的类作为成员变量 private Interface proxied; //构造方法中传入 public SimpleProxy(Interface proxied) { this.proxied = proxied; }//实现接口 @Override public void doSomething() { System.out.println("SimpleProxy doSomething"); proxied.doSomething(); }@Override public void somethingElse(String args) { System.out.println("SimpleProxy somethingElse" + args); proxied.somethingElse(args); } }

//测试一下 public class SimpleProxyDemo {public static void consumer(Interface iface) { iface.doSomething(); iface.somethingElse(":jyu"); }public static void main(String[] args) { consumer(new RealObject()); consumer(new SimpleProxy(new RealObject())); } }

输出:
doSomething somethingElse:jyu SimpleProxy doSomething doSomething SimpleProxy somethingElse:jyu somethingElse:jyu

动态代理 动态代理也叫做JDK代理、接口代理。不需要实现目标对象的接口。生成代理对象,使用的是Java的API,动态的在内存中构件代理对象(这需要我们指定创建代理对象/目标对象的接口的类型)。
看下下面的例子。还是使用上面的Interface接口,和RealObject类。
//实现InvocationHandler接口 public class DynamicProxyHandler implements InvocationHandler {private Object proxied; public DynamicProxyHandler(Object proxied) { this.proxied = proxied; }//覆写invoke方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("*** proxy:" + proxy.getClass() + ",\nmethod:" + method + ",\nargs:" + args); if (args != null) { for (Object arg : args) { System.out.println("" + arg); } } return method.invoke(proxied, args); } }

//测试一下 public class SimpleDynamicProxy {public static void consumer(Interface iface) { iface.doSomething(); iface.somethingElse(" jyu"); }public static void main(String[] args) { RealObject real = new RealObject(); consumer(real); Interface proxy = (Interface) Proxy.newProxyInstance( Interface.class.getClassLoader(), new Class[]{Interface.class}, new DynamicProxyHandler(real)); consumer(proxy); } }

//输出: doSomething somethingElse jyu *** proxy:class com.sun.proxy.$Proxy0, method:public abstract void proxy.Interface.doSomething(), args:null doSomething *** proxy:class com.sun.proxy.$Proxy0, method:public abstract void proxy.Interface.somethingElse(java.lang.String), args:[Ljava.lang.Object; @355da254 jyu somethingElse jyu

PS:《java编程思想》中给咱们留的作业:使用动态代理来编写一个系统以实现事务,其中,代理在被代理的调用执行成功时(不抛出异常)执行提交,而在其执行失败时执行回滚。你的提交和回滚都针对一个外部的文本文件,该文件不在Java异常的控制控制范围之内。你必须注意操作的原子性
3.Cglib代理 cglib在android中是不能使用的,因此咱们这里先不讨论这项技术了。有兴趣的同学可以看看类似的文章。

将cglib动态代理思想带入Android开发
参考资料
  • 【Java基础】动态代理实现AOP之控制事务
  • java设计模式-代理模式(Proxy)

    推荐阅读