Retrofit(一)动态代理的作用

Retrofit对动态代理模式的利用是最巧妙的。你需要事先理解动态代理模式的实现原理

动态代理模式中,系统会自动实现需要代理的接口,自动生成一个代理类的.class文件,这个自动生成的代理类中,所有的代理方法都是调用InvocationHandler对象。这一点是最重要的。方便参数以注解的方式在各接口方法上定义好。

如何理解上面加黑的那句话呢? 请看下面的代码:

public interface RetrofitService{
    @GET("/service/get/")
    Call<ResponseInfo<User>> get(@HeaderMap Map<String, String>header, @Query("userId") String id);

}

public class RetrofitService$12345 implement RetrofitService{
    private InvocationHandler handler;

    public RetrofitService$12345(InvocationHandler handler){
         this.handler = handler;
    }

    @GET("/service/get/")
    public Call<ResponseInfo<User>> get(@HeaderMap Map<String, String>header, 
                                 @Query("userId") String id){
      return handler.invoke(null, 
                            RetrofitService.getClass().getMethod("get"),
                            new Objectt[]{header, id});
    }

}
  • RetrofitService是开发者定义的http访问接口。
  • RetrofitService$12345是系统自动生成的代理类,它实现了RetrofitService。
  • RetrofitService目前只有一个get方法, 即使更多的方法, 里面也是调用handler.invoke()。

下面看看Retrofit中使用动态代理的create方法。

  public <T> T create(final Class<T> service) {
    validateServiceInterface(service);
    return (T)
        Proxy.newProxyInstance(
            service.getClassLoader(),
            new Class<?>[] {service},
            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);
                }
                args = args != null ? args : emptyArgs;
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }
  • 由于每一个接口方法都只调用传进去的new InvocationHandler()对象。使得所有的接口方法都会调到 Object invoke()这个方法里来。
  • 接下来的操作,就是解析注解,封装request, 封装Call, 返回Call或者通过CallAdapter返回其他可执行Call的对象。如下图:
  • platform.isDefaultMethod(method), 是判断接口方法是不是interface里面的default方法,这是java8的语言特性, 在interface里面也可以定义方法体。
  • platform.invokeDefaultMethod(method, service, proxy, args), 如果这个方法是接口default方法, 就调用这个defualt方法。
  • 以上两点对retrofit的使用都不重要,作者只是为了把异常case写全。重要的是loadSerivceMethod()这个方法。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值