动态代理
说到动态代理,总是离不开静态代理和代理模式。静态代理总是要写接口,然后代理类和被代理类实现该接口,客户端通过代理类使用接口提供的功能,而代理类把功能实际的工作转到被代理类。问题在哪里,每次我们都懂得去实现代理类和代理类,如果很多个接口,这样会很累的,毕竟程序员都是懒的。再说如果这样,用Retrofit这种第三方库,怎么知道用户创建什么样的接口,怎么去实现他们功能?那就是利用Java的动态代理技术了。动态代理在使用上也可以理解是一套模板。
首先,定义接口,以及实现类,也就是我们对外提供的功能。
public interface Service {
void coding();
}
public class CoderService implements Service {
@Override
public void coding() {
System.out.println(“提供编程服务”);
}
}
复制代码
第二,实现InvocationHandler的子类。核心点在于实现invoke函数,调用接口的函数都会转到这里来。
public class Handler implements InvocationHandler {
private Object service;
public Handler(Object service) {
this.service = service;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("开发了");
method.invoke(service,objects);
System.out.println("结束了");
return null;
}
}
复制代码
最后,创建Proxy.newProxyInstance接口对象。在Java中,接口和抽象类是不能被直接实例化的。
public class Main {
public static void main(String[] args) {
Service service = new CoderService();
InvocationHandler handler = new Handler(service);
Service se = (Service) Proxy.newProxyInstance(Service.class.getClassLoader(), new Class[]{Service.class}, handler);
se.coding();
}
}
复制代码
这样就可以通过实例化的接口对象,使用相关功能。
Retrofit通过在InvocationHandler的invoke解析Method来获得网络请求所需要的的数据。
总结
Retrofit通过Java动态代理技术生成我们请求接口的对象,而我们调用对象的任何函数时,其实都转到InvocationHandler对象的invoke函数。而invoke函数的主要工作就是解析我们在接口中定义函数,包括解析注解,参数注解及值,以及返回类型,然后封装到RequestFactory,然后通过HttpServiceMethod.parseAnnotations函数,查找合适的请求适配器和响应转换器,最后将RequestFactory和适配器、转换器封装成HttpServiceMethod的子类,并调用其invoke函数,通过OkHttp发起网络请求。
链接:https://juejin.cn/post/6941585326675034143