在 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 是怎么使用的,自己写个小荔枝。
- 定义一个接口
public interface Service {
int getInt();
}
- 使用动态代理
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 动态代理就是使用 ...