Android 中的动态代理
动态代理的优点有:
- 隐藏委托类的实现
- 解耦,不改变委托类代码情况下做一些额外处理
- 方便对代理类的函数做统一或特殊处理
实现步骤
-
新建接口类
public interface Subject { public void doSomething(); }
-
创建委托类并实现定义的接口类
public class RealSubject implements Subject { public void doSomething() { System.out.println( "call doSomething()" ); } }
-
创建代理帮助类,实现InvocationHandler接口
InvocationHandler:是负责连接代理类和委托类的中间类必须实现的接口
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyHandler implements InvocationHandler { private Object tar; //绑定委托对象,并返回代理类 public Object bind(Object tar) { //tar属性表示委托类对象。 this.tar = tar; //绑定该类实现的所有接口,取得代理类 return Proxy.newProxyInstance( //loader表示类加载器 tar.getClass().getClassLoader(), //interfaces表示委托类的接口,生成代理类时需要实现这些接口 tar.getClass().getInterfaces(), //InvocationHandler实现类对象,负责连接代理类和委托类的中间类 this); } //当proxy生成字节码时 会调用invoke方法 public Object invoke(Object proxy , Method method , Object[] args)throws Throwable { Object result = null; //这里就可以进行所谓的AOP编程了 //在调用具体函数方法前,执行功能处理 result = method.invoke(tar,args); //在调用具体函数方法后,执行功能处理 return result; } }
public class TestProxy { public static void main(String args[]) { ProxyHandler proxy = new ProxyHandler(); //绑定该类实现的所有接口 Subject sub = (Subject) proxy.bind(new RealSubject()); //调用代理对象的每个函数实际最终都是调用了InvocationHandler的invoke函数。 sub.doSomething(); } }
原理
动态代理可以理解为双向静态代理,我们先是创建委托类B,系统动态生成代理类A。
然后创建一个实现了InvocationHandler的子类C,子类连接代理类A和委托类B。
它是代理类A的委托类,是委托类B的代理类。
用户直接调用代理类A的对象,A将调用转给它的委托类C,委托类C再将调用转发给它的委托类B。
用到的地方
- jfinal框架中的拦截器机制就是基于动态代理实现的。
- 使用 cglib 动态代理
- 将InvocationHandler抽象为一个Invocation,在invoke方法中实现调用委托类方法之前对本次请求进行拦截。
- Retrofit:简化了网络请求