「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」
接# Retrofit(一)篇,这篇主要对动态代理进行分析
一、代理
代理(Proxy)是一种设计模式,代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。代理分为静态代理和动态代理。
1. 静态代理
静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类。
静态代理总结:
1.可以做到在不修改目标对象的功能前提下,对目标功能扩展.
2.缺点:
- 因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多。同时一旦接口增加方法,目标对象与代理对象都要维护。
2. 动态代理
动态代理有以下特点:
- 代理对象,不需要实现接口
- 代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
- 动态代理也叫做:JDK代理,接口代理
JDK提供了Proxy.newProxyInstance(),直接返回代理实例
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
Class<?> cl = getProxyClass0(loader, intfs);
try {
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
cons.setAccessible(true);
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
. . .
}
}
2. 动态代理在Retrofit中的应用
源码在# Retrofit(一)中已经有了,有需要的可以自行查看
public <T> T create(final Class<T> service) {
. . .
}
看到new InvocationHandler(){},等于变相实现了InvocationHandler,另外,Proxy.newProxyInstance最终会调用一个 native 方法,动态生成一个对象
2.总结
Retrofit中使用了动态代理是不错,但是并不是为了真正的代理才使用的,它只是为了动态代理一个非常重要的功能,就是“拦截”功能。我们知道动态代理中自动生成的A对象的所有方法执行都会调用实际代理类A中的invoke方法,再由我们在invoke中实现真正代理的逻辑,实际上也就是A的所有方法都被A对象给拦截了。而Retrofit最重要的是什么?就是把一个网络执行变成像方法调用一样方便的过程,也就是一个网络调用你只需要在你创建的接口里面通过注解进行设置,然后通过retrofit创建一个api然后调用,就可以自动完成一个Okhttp的Call的创建