Retrofit中的动态代理

Retrofit使用动态代理来生成api的类和实例,开发过程中却无感知,下面是一个最朴素的使用方式:

  1. 初始化retrofit
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://" + server.getHostName() + ":" + server.getPort())
                .addConverterFactory(GsonConverterFactory.create())
                .client(httpClient.build())
                .build();


  1. 定义接口
public interface Api {
    @GET("/")
    @Headers("Content-Type:application/json")
    Call<JsonResPonse> getMethodJsonResp(@Query("id") String id);
}
  1. 创建api
Api api = retrofit.create(Api.class);
  1. 发请请求:
JsonResPonse fromJson = api.getMethodJsonResp("1").execute().body();

用户只是写了一个请求接口Api,以及定义了一些方法。可以猜测的是在调用create的时候,生成相应的类,以及实例,在调用方法的时候,会对请求,返回,以及注解进行处理。
只要找到生成的类,再反编译便一目了然。

如何获得动态代理生成的类

自定义的Api接口,为了方便观察,这里只使用了一个方法:

public interface Api {
    @GET("/")
    @Headers("Content-Type:application/json")
    Call<JsonResPonse> getMethodJsonResp(@Query("id") String id);
    }

在api创建之前加入这段代码,用来保存生成的class文件用:

Properties properties = System.getProperties();
properties.put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

运行后,生成的class文件保存在com.sun.proxy文件夹下面,文件是以$Proxy+数字命名.用as打开后:

public final class $Proxy0 extends Proxy implements Api {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final Call getMethodJsonResp(String var1) throws  {
        try {
            return (Call)super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("com.tcl.component.portal.Api").getMethod("getMethodJsonResp", Class.forName("java.lang.String"));
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

可见当调用getMethodJsonResp时会调用:

  return (Call)super.h.invoke(this, m3, new Object[]{var1});

super.h便是InvocationHandler,在retrofit creat方法中实现:

 new InvocationHandler() {
          private final Platform platform = Platform.get();
          private final Object[] emptyArgs = new Object[0];

          @Override public @Nullable 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);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });

可见处理顺序为:

生成类和实例
检测缓存
create
getMethodJsonResp
invoke
处理注解
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值