Retrofit 看动态代理

在 Retrofit 中一个重要点就是动态代理,我们只需要定义 Service 接口,并在里面定义需要的网络请求方法即可,具体这个 Service 接口是怎样实现的?

  public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public 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);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

其中看下 Proxy.newProxyInstance 和 InvocationHandler 是怎么使用的,自己写个小荔枝。

  1. 定义一个接口
public interface Service {

    int getInt();

}
  1. 使用动态代理

public class Main {

    public static void main(String[] args) {

        Service service = (Service) Proxy.newProxyInstance(
                Service.class.getClassLoader(),
                new Class<?>[]{Service.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if (method.getDeclaringClass() == Object.class) {
                            return method.invoke(this, args);
                        }

                        System.out.println(method.getName());
                        return 12;
                    }
                });

        System.out.println(service.toString());
        System.out.println(service.getInt());
    }
}
----- 
输出
Main$1@4b67cf4d
getInt
12

em 动态代理就是使用 ...

猜你喜欢

转载自blog.csdn.net/weixin_34054866/article/details/87028930