代理模式分为静态代理和动态代理
静态代理
就拿网络请求来说
先定义一个网络请求统一接口INetworkRequester 里面有一个post方法
public interface INetworkRequester{
void post();
}
网络请求框架有很多种比如早期的 Volley 现在的Okhttp
public class OkhttpNetworkRequester implements INetworkRequester{
public void post(){
Log.i("ancely_proxy","OkhttpNetworkRequester.post()");
}
}
public class VolleyNetworkRequester implements INetworkRequester{
public void post(){
Log.i("ancely_proxy","VolleyNetworkRequester.post()");
}
}
在请求网络的时候有一个代理的网络请求器,在请求网络的时候我们并不关心里面是怎么请求的,只要能达到目的就可以
public class ProxyNetworkRequester implements INetworkRequester{
private INetworkRequester mRequester;
public ProxyNetworkRequester(INetworkRequester requester){
mRequester = requester;
}
public void post(){
mRequester.post();
}
}
假如我们一开始使用的是Volley请求库,我们只需要这样调用
INetworkRequester requester = new ProxyNetworkRequester(new VolleyNetworkRequester());
requester.post();//这样用的就是Volley框架
//后面更新迭代,Volley不受欢迎,Okhttp流行起来了我们要换库就非常的方便
INetworkRequester requester = new ProxyNetworkRequester(new OkhttpNetworkRequester());
requester.post();//这样用的就是Okhttp框架
当然比如常用的Json序列化库也可以同样操作
动态代理
动态代理使用起来其实很简单,主要是调用Proxy的newProxyInstance方法
INetworkRequester requester = new ProxyNetworkRequester(new VolleyNetworkRequester());
Object proxyInstance = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{INetworkRequester.class}, (o, method, objects) -> {
Log.i("ancely_proxy","newProxyInstance.post()");
return method.invoke(requester,objects);
});
INetworkRequester requester1 = (INetworkRequester) proxyInstance;
Log.i("ancely_proxy","proxyInstance hashCode: ."+ requester1.hashCode());
requester1.post();
动态代理原理
-
类的完整生命周期
Java源文件---->编译生成java字解码.class文件(实实在在的文件)---->通过类加载机制变成Class对象----->然后再实例化出对象—>卸载 -
动态代理的class对象是怎么来的
- 逻辑在Proxy的newProxyInstance里
- 通过Proxy里的getProxyClass0方法创建了一个Class对象cl,怎么生成的我们不关心
- 获取Class对象的构造方法cl.getConstructor(constructorParams);
- 反射创建对象cons.newInstance(h);h就是我们newProxyInstance方法里传进定数的InvocationHandler接口
源码如下
private static final Class<?>[] constructorParams = new Class[]{InvocationHandler.class};
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h) {
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
//创建了一个Class对象
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(h);
} catch (Exception e) {
throw new InternalError(e.toString(), e);
}
}
内存中生成的Class是什么样的,通过以下方法可以获取
String name = INetworkRequester.class.getName() + "$Proxy0";
byte[] bytes = ProxyGenerator.generateProxyClass(name, new Class[]{INetworkRequester.class});
try {
FileOutputStream fos = new FileOutputStream("complier/" + name + ".class");
fos.write(bytes);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
package com.ancely.complier;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class INetworkRequester$Proxy0 extends Proxy implements INetworkRequester {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public INetworkRequester$Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void post() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("com.ancely.complier.INetworkRequester").getMethod("post");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
通过上面文件就非常清楚动态代理的原理了
- 1.通过Proxy.newProxyInstance创建了一个Object对象 proxyObject
- 2.通过生成的文件可以发现 proxyObject是继承了Proxy 实现了代理接口INetworkRequester
- 3.在生成的Class文件的构造方法中传入了我们在newProxyInstance方法中传入了InvocationHandler参数,
- 4.所以生成的Class文件执有了一个InvocationHandler h
- 5.当我们调用了proxyObject对应的方法时就会调用InvocationHandler h的invoke方法