动态代理示例:
动态代理对象是如何生成的?invoke方法又是何时执行的?,阅读静态工厂方法的代码:
getProxyClass0(loader, intfs)方法实现如下:
其内部是调用了proxyClassCache,这个是动态代理对象缓存,代码如下.这段代码有点麻烦,似乎是当对象不存在时创建新对象,不过最重要的是subKeyFactory的apply()方法
这个方法重要的是
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
apply方法是用来生成字节码数组的:这里可以很清楚地知道生成的包名,类名是啥
生成字节码数组是通过如下代码:
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces);
这个方法有些复杂,就不做研究了
可以写一个程序,单独测试这个方法,让其生成字节码文件,打开class文件就知道invoke方法是如何调用的:
打开生成的文件,可以观察到: 代理类实现了相关的接口,并重写了相关方法,在调用时实际是调用了InvocationHandler的invode方法
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.RandomAccess;
public final class $Proxy11 extends Proxy implements List, RandomAccess, Cloneable, Serializable {
private static Method m14;
private static Method m13;
private static Method m19;
private static Method m2;
private static Method m25;
private static Method m9;
private static Method m5;
private static Method m16;
private static Method m3;
private static Method m17;
private static Method m18;
private static Method m24;
private static Method m10;
private static Method m8;
private static Method m20;
private static Method m21;
private static Method m4;
private static Method m12;
private static Method m1;
private static Method m15;
private static Method m23;
private static Method m7;
private static Method m22;
private static Method m11;
private static Method m0;
private static Method m6;
public $Proxy11(InvocationHandler var1) throws {
super(var1);
}
public final List subList(int var1, int var2) throws {
try {
return (List)super.h.invoke(this, m14, new Object[]{Integer.valueOf(var1), Integer.valueOf(var2)});
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final int size() throws {
try {
return ((Integer)super.h.invoke(this, m13, (Object[])null)).intValue();
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final Iterator iterator() throws {
try {
return (Iterator)super.h.invoke(this, m19, (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 boolean retainAll(Collection var1) throws {
try {
return ((Boolean)super.h.invoke(this, m25, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void clear() throws {
try {
super.h.invoke(this, m9, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final boolean remove(Object var1) throws {
try {
return ((Boolean)super.h.invoke(this, m5, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final Object[] toArray(Object[] var1) throws {
try {
return (Object[])super.h.invoke(this, m16, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final boolean add(Object var1) throws {
try {
return ((Boolean)super.h.invoke(this, m3, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final boolean addAll(int var1, Collection var2) throws {
try {
return ((Boolean)super.h.invoke(this, m17, new Object[]{Integer.valueOf(var1), var2})).booleanValue();
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final boolean addAll(Collection var1) throws {
try {
return ((Boolean)super.h.invoke(this, m18, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final boolean removeAll(Collection var1) throws {
try {
return ((Boolean)super.h.invoke(this, m24, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final boolean contains(Object var1) throws {
try {
return ((Boolean)super.h.invoke(this, m10, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final int indexOf(Object var1) throws {
try {
return ((Integer)super.h.invoke(this, m8, new Object[]{var1})).intValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final Object set(int var1, Object var2) throws {
try {
return (Object)super.h.invoke(this, m20, new Object[]{Integer.valueOf(var1), var2});
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final boolean containsAll(Collection var1) throws {
try {
return ((Boolean)super.h.invoke(this, m21, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void add(int var1, Object var2) throws {
try {
super.h.invoke(this, m4, new Object[]{Integer.valueOf(var1), var2});
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final int lastIndexOf(Object var1) throws {
try {
return ((Integer)super.h.invoke(this, m12, new Object[]{var1})).intValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final boolean equals(Object var1) throws {
try {
return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final Object[] toArray() throws {
try {
return (Object[])super.h.invoke(this, m15, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final ListIterator listIterator(int var1) throws {
try {
return (ListIterator)super.h.invoke(this, m23, new Object[]{Integer.valueOf(var1)});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final Object get(int var1) throws {
try {
return (Object)super.h.invoke(this, m7, new Object[]{Integer.valueOf(var1)});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final ListIterator listIterator() throws {
try {
return (ListIterator)super.h.invoke(this, m22, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final boolean isEmpty() throws {
try {
return ((Boolean)super.h.invoke(this, m11, (Object[])null)).booleanValue();
} 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)).intValue();
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final Object remove(int var1) throws {
try {
return (Object)super.h.invoke(this, m6, new Object[]{Integer.valueOf(var1)});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
static {
try {
m14 = Class.forName("java.util.List").getMethod("subList", new Class[]{Integer.TYPE, Integer.TYPE});
m13 = Class.forName("java.util.List").getMethod("size", new Class[0]);
m19 = Class.forName("java.util.List").getMethod("iterator", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m25 = Class.forName("java.util.List").getMethod("retainAll", new Class[]{Class.forName("java.util.Collection")});
m9 = Class.forName("java.util.List").getMethod("clear", new Class[0]);
m5 = Class.forName("java.util.List").getMethod("remove", new Class[]{Class.forName("java.lang.Object")});
m16 = Class.forName("java.util.List").getMethod("toArray", new Class[]{Class.forName("[Ljava.lang.Object;")});
m3 = Class.forName("java.util.List").getMethod("add", new Class[]{Class.forName("java.lang.Object")});
m17 = Class.forName("java.util.List").getMethod("addAll", new Class[]{Integer.TYPE, Class.forName("java.util.Collection")});
m18 = Class.forName("java.util.List").getMethod("addAll", new Class[]{Class.forName("java.util.Collection")});
m24 = Class.forName("java.util.List").getMethod("removeAll", new Class[]{Class.forName("java.util.Collection")});
m10 = Class.forName("java.util.List").getMethod("contains", new Class[]{Class.forName("java.lang.Object")});
m8 = Class.forName("java.util.List").getMethod("indexOf", new Class[]{Class.forName("java.lang.Object")});
m20 = Class.forName("java.util.List").getMethod("set", new Class[]{Integer.TYPE, Class.forName("java.lang.Object")});
m21 = Class.forName("java.util.List").getMethod("containsAll", new Class[]{Class.forName("java.util.Collection")});
m4 = Class.forName("java.util.List").getMethod("add", new Class[]{Integer.TYPE, Class.forName("java.lang.Object")});
m12 = Class.forName("java.util.List").getMethod("lastIndexOf", new Class[]{Class.forName("java.lang.Object")});
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
m15 = Class.forName("java.util.List").getMethod("toArray", new Class[0]);
m23 = Class.forName("java.util.List").getMethod("listIterator", new Class[]{Integer.TYPE});
m7 = Class.forName("java.util.List").getMethod("get", new Class[]{Integer.TYPE});
m22 = Class.forName("java.util.List").getMethod("listIterator", new Class[0]);
m11 = Class.forName("java.util.List").getMethod("isEmpty", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m6 = Class.forName("java.util.List").getMethod("remove", new Class[]{Integer.TYPE});
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
总结
JDK实现动态代理的过程如下:
克隆传入的接口Class数组(通过clone()方法)
查找或者生成实现了接口数组中所有接口的动态代理类的Class
利用动态代理类的Class获取Constructor对象,利用我们传入的InvocationHandler实现类对象作为输入参数,生成动态代理类的对象动态代理类对象的性质:
实现了传入的接口Class数组中所有的接口
这些接口中如果含有非public的接口,非public接口必须在同一个包下面,而且代理类也必须和他们在同一包下,要不代理类必然访问
不了部分接口
父类(Proxy)有一个InvocationHandler的成员变量,它的值是我们在Proxy.newInstance()方法中传入的,子类的所有方法都是围绕InvocationHandler进行.