「必知必会」Android 中的动态代理

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:简化了网络请求

你可能感兴趣的:(「必知必会」Android 中的动态代理)