上一节《设计模式之代理模式》中我们已经对设计模式中的代理模式做了一个简单的介绍,这一节将会对Java的动态的代理原理、源码进行深入的分析(注意:这里分析的是JDK1.8中的动态代理的源码)。篇幅有点长,花了好几天的时间才写完,感觉身体被掏空。。。。。。
一、概述
上节介绍过,Java的动态代理是在运行时动态产生的,其底层是通过反射实现的。Java的动态代理要求目标类必须实现接口,否则无法被代理。Java动态代理中最关键的有两个:
- InvocationHandler接口:代理类不再实现目标类的接口,而是实现InvocationHandler接口,并且重写其 public Object invoke(Object proxy, Method method, Object[] args) 方法,参数proxy是产生的代理对象,method是要执行的目标类的接口中的方法,args是要执行的方法传入的参数。产生的代理类执行方法时,其实执行的就是invoke方法。
- Proxy类:Proxy提供了静态方法用于生成代理类, public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h),loader是目标类的类加载器,interfaces是目标类的全部接口,h是InvocationHandler接口的子类的实例。
上节测试代码如下,InvocationHandler是控制代理类的方法执行的,代理类的产生是Proxy.newProxyInstance方法产生的。
public class TestJavaDynamicProxy {
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
UserHandle target = new UserHandle();
LogProxyHandle invocationHandler = new LogProxyHandle(target);
Handle handle = (Handle) Proxy.newProxyInstance(target.getClass()
.getClassLoader(), target.getClass().getInterfaces(),
invocationHandler);
handle.add();
}
}
二、Proxy.newProxyInstance方法
- 可以看到newProxyInstance()方法中主要做了如下几件事:
- 对目标接口进行克隆
- 权限校验
- getProxyClass0(loader, intfs)方法获取代理类class对象,重点
- 获取代理类中参数为InvocationHandler.class的构造方法
- 执行构造方法返回实例对象
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
//对目标类接口进行克隆
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
//权限校验
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
*/
//获取代理类clsss对象(重点)
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
//使用指定的invocation handler调用代理类的构造函数
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//获取代理类中参数为InvocationHandler.class的构造方法
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
// 检测构造器是否是Public修饰,如果不是则强行转换为可以访问的
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
//执行构造方法,返回代理类实例
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
下面我们重点看下getProxyClass0(loader, intfs)方法
三、Proxy.getProxyClass0方法
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
//判断接口数量
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// If the proxy class defined by the given loader implementing
// the given interfaces exists, this will simply return the cached copy;
// otherwise, it will create the proxy class via the ProxyClassFactory
//根据类加载器和接口数组,从缓存中获取代理类class对象
return proxyClassCache.get(loader, interfaces);
}
里面最重要的是这个方法:proxyClassCache.get(loader, interfaces),根据类加载器和接口数组,从proxyClassCache缓存中获取代理类class对象。proxyClassCache是什么呢?proxyClassCache是Proxy类中定义的一个静态成员变量,类型是WeakCache,缓存就是从WeakCache中获取的。
/**
* a cache of proxy classes
*/
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
四、WeakCache类
WeakCache从字面意思看是虚缓存,缓存(键、子键)->值的映射对。WeakCache<K, P, V>中定义了三个泛型K、P、V:其中K是key也就是键;P是参数,可以通过K和P计算出子键;V是value值。通过proxyClassCache.get(loader, interfaces)方法可知:当前的K是类加载器,P是目标类的接口类数组,V就是要产生的代理类class对象。键和值是弱引用,但子键是强引用的。
强引用(StrongReference)
强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。 强引用其实也就是我们平时A a = new A()这个意思。
弱引用(WeakReference)
在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果在创建WeakReference对象的时候,使用了一个ReferenceQueue对象作为参数提供给WeakReference的构造方法,当弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。ReferenceQueue这个名字也可以看出,它是一个队列,当我们调用它的poll()方法的时候,如果这个队列中不是空队列,那么将返回队列前面的那个Reference对象。
在任何时候,我们都可以调用ReferenceQueue的poll()方法来检查是否有它所关心的非强可及对象被回收。如果队列为空,将返回一个null,否则该方法返回队列中前面的一个Reference对象。利用这个方法,我们可以检查哪个WeakReference所弱引用的对象已经被回收。于是我们可以把这些失去所弱引用的对象的WeakReference对象清除掉。常用的方式为:
WeakReference ref = null;
while ((ref = (CacheKey) q.poll()) != null) {
// 清除ref
}
具体的关于Java的四种引用类型,可以参考《Java四种引用类型: 强引用、弱引用、软引用、虚引用》,
主要成员变量如下:
refQueue:弱引用队列,在这里其中存放的是弱引用CacheKey,CacheKey其实就是对WeakCache中的K键的封装,如果CacheKey被垃圾回收了,则其会进入引用队列,我们通过refQueue.poll()获取到CacheKey,从缓存中删除被垃圾回收掉的CacheKey
map:其类型ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>>,把泛型用这样表示ConcurrentMap<A, ConcurrentMap<B, Supplier<V>>>:A即CacheKey,本例中也就是类加载器;B即subKey子键,是由KeyFactory(subKeyFactory.apply(key, parameter))获得的。
reverseMap:暂时不管
subKeyFactory:Proxy的内部类,子键工厂KeyFactory,其apply(key, parameter)方法计算subKey
valueFactory:Proxy的内部类,value工厂ProxyClassFactory,其public Class<?> apply(ClassLoader loader, Class<?>[] interfaces)生产代理类class对象。
final class WeakCache<K, P, V> {
//引用队列
private final ReferenceQueue<K> refQueue
= new ReferenceQueue<>();
// the key type is Object for supporting null key
//key类型为Object,支持null key,这里的null key是指new Object();
private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
= new ConcurrentHashMap<>();
private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
= new ConcurrentHashMap<>();
private final BiFunction<K, P, ?> subKeyFactory;
private final BiFunction<K, P, V> valueFactory;
public WeakCache(BiFunction<K, P, ?> subKeyFactory,
BiFunction<K, P, V> valueFactory) {
this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
this.valueFactory = Objects.requireNonNull(valueFactory);
}
public V get(K key, P parameter) {
//省略,后面进行分析
}
}
五、WeakCache.get方法
public V get(K key, P parameter) {
Objects.requireNonNull(parameter);
//清理过期对象
expungeStaleEntries();
//缓存key对象CacheKey
Object cacheKey = CacheKey.valueOf(key, refQueue);
// lazily install the 2nd level valuesMap for the particular cacheKey
//通过key:CacheKey对象获取vlaue ConcurrentMap<Object, Supplier<Class<?>>>,泛型Class<?>就是代理类Class对象
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
//如果valuesMap为空
if (valuesMap == null) {
//如果cacheKey不存在则放进去一个new的Map,否则返回旧值
ConcurrentMap<Object, Supplier<V>> oldValuesMap
= map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>());
//如果旧值map不为空,赋值给valusMap
if (oldValuesMap != null) {
valuesMap = oldValuesMap;
}
}
// create subKey and retrieve the possible Supplier<V> stored by that
// subKey from valuesMap
//通过类加载和接口class数组计算子键subKey,因为我们的目标类只实现了一个接口,所以这里返回的是Key1<接口Class>
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
//根据subKey从valuesMap中获取Supplier<代理类Class>
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
while (true) {
//如果从valuesMap中获取的supplier不为空
if (supplier != null) {
// supplier might be a Factory or a CacheValue<V> instance
//4,通过get()方法返回代理类class对象
V value = supplier.get();
if (value != null) {
//5,返回代理类class对象
return value;
}
}
// else no supplier in cache
// or a supplier that returned null (could be a cleared CacheValue
// or a Factory that wasn't successful in installing the CacheValue)
// lazily construct a Factory
//如果factory为空,则new一个Factory对象
if (factory == null) {
//1,Factory(实现了Supplier<V>接口):实现值的延迟同步构造并将其安装到缓存中的工厂供应商。
factory = new Factory(key, parameter, subKey, valuesMap);
}
if (supplier == null) {
//2,如果subKey不存在则将上面构造的factory对象放入valuesMap,否则返回旧值supplier
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
// successfully installed Factory
//3,赋值
supplier = factory;
}
// else retry with winning supplier
//如果旧值supplier不为空,则继续重试
} else {
//从valuesMap中获取的supplier不为空,但是其get返回的代理类Class为空
//用factory替换supplier
if (valuesMap.replace(subKey, supplier, factory)) {
// successfully replaced
// cleared CacheEntry / unsuccessful Factory
// with our Factory
supplier = factory;
} else {
// retry with current supplier
//替换失败,继续重试
supplier = valuesMap.get(subKey);
}
}
}
}
进来会先执行expungeStaleEntries()方法清理过期对象,这里就是利用弱引用被垃圾回收后进入ReferenceQueue队列的特性,poll()出已经被回收的CacheKey,把它从map中清除,expungeStaleEntries内部实现如下
private void expungeStaleEntries() {
CacheKey<K> cacheKey;
while ((cacheKey = (CacheKey<K>)refQueue.poll()) != null) {
//清除被垃圾回收的CacheKey
cacheKey.expungeFrom(map, reverseMap);
}
}
while循环里面我在代码中标注了顺序,第一次进来的执行顺序为1,2,3,4,5
步骤1,Factory类是WeakCache的内部类,实现了Supplier<V>接口,其get方法返回代理类对象
步骤2,判断子键是否存在,如果不存在则放入1中构造的factory,并返回null,如果存在则只返回原先存放的Supplier的实现类对象
步骤3,步骤2中返回的是null,将factory赋值给supplier
步骤4,步骤3执行完成后进行下一次while循环,进入步骤4,实际上执行的就是步骤2构造的factory对象的get方法
步骤5,判断4中返回的value如果不为空则直接返回
六、Factory.get
Factory类是WeakCache的内部类,可以操作其成员变量,我们重点关注如下这行代码:其中的valueFactory就是WeakCache中在Proxy中传入的ProxyClassFactory对象,ProxyClassFactory这个类的apply方法是生成代理类的关键所在。
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
public synchronized V get() { // serialize access
// re-check
Supplier<V> supplier = valuesMap.get(subKey);
//重复校验是否被修改过
if (supplier != this) {
// something changed while we were waiting:
// might be that we were replaced by a CacheValue
// or were removed because of failure ->
// return null to signal WeakCache.get() to retry
// the loop
return null;
}
// else still us (supplier == this)
// create new value
V value = null;
try {
//valueFactory(ProxyClassFactory)的apply方法,创建代理类
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
} finally {
if (value == null) { // remove us on failure
valuesMap.remove(subKey, this);
}
}
// the only path to reach here is with non-null value
//判断生成的value是否不为空
assert value != null;
// wrap value with CacheValue (WeakReference)
//用CacheValue(实现了Supplier接口)包装value
CacheValue<V> cacheValue = new CacheValue<>(value);
// try replacing us with CacheValue (this should always succeed)
//用cacheVaule替换supplier
if (valuesMap.replace(subKey, this, cacheValue)) {
// put also in reverseMap
reverseMap.put(cacheValue, Boolean.TRUE);
} else {
throw new AssertionError("Should not reach here");
}
// successfully replaced us with new CacheValue -> return the value
// wrapped by it
return value;
}
七、ProxyClassFactory.apply
该类是Proxy的内部类,其中定义了两个成员变量:所有代理类的前缀$Proxy的字符串,还有一个用于生成唯一代理类名称的下一个数字编号的AtomicLong类型的变量。
在apply方法中判断了接口中如果没有非公共接口,则生成的代理类包名用 com.sun.proxy,
代理类全名,如果没有非公共接口,则proxyName=com.sun.proxy.$Proxy0(1,2,3,4......)
最关键是这行byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags),用于生成代理类class文件。
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
// prefix for all proxy class names
//所有代理类的前缀
private static final String proxyClassNamePrefix = "$Proxy";
// next number to use for generation of unique proxy class names
//用于生成唯一代理类名称的下一个数字编号
private static final AtomicLong nextUniqueNumber = new AtomicLong();
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
/*
* Verify that the class loader resolves the name of this
* interface to the same Class object.
*/
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
//验证类加载器是否将此接口的名称解析为同一类对象
if (interfaceClass != intf) {
throw new IllegalArgumentException(
intf + " is not visible from class loader");
}
/*
* Verify that the Class object actually represents an
* interface.
*/
//判断interfaceClass是否是接口
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
/*
* Verify that this interface is not a duplicate.
*/
//验证此接口不是重复的
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
}
//代理类的包名
String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
/*
* Record the package of a non-public proxy interface so that the
* proxy class will be defined in the same package. Verify that
* all non-public proxy interfaces are in the same package.
*/
//记录非公共代理接口的包,以便在同一包中定义代理类。验证所有非公共代理接口都在同一个包中
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
//目标类的非公共接口不在一个包里面
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}
if (proxyPkg == null) {
// if no non-public proxy interfaces, use com.sun.proxy package
//如果没有非公共接口,则包名用 com.sun.proxy
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
/*
* Choose a name for the proxy class to generate.
*/
//代理类名自增序号
long num = nextUniqueNumber.getAndIncrement();
//代理类名,如果没有非公共接口,则proxyName=com.sun.proxy.$Proxy0(1,2,3,4......)
String proxyName = proxyPkg + proxyClassNamePrefix + num;
/*
* Generate the specified proxy class.
*/
//生成代理类class文件
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
//返回代理类对象
return defineClass0(loader, proxyName,proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
/*
* A ClassFormatError here means that (barring bugs in the
* proxy class generation code) there was some other
* invalid aspect of the arguments supplied to the proxy
* class creation (such as virtual machine limitations
* exceeded).
*/
throw new IllegalArgumentException(e.toString());
}
}
}
八、ProxyGenerator.generateProxyClass方法
ProxyGenerator类的关键代码如下, 如果想查看源码的话可以通过Idea工具打开看下,eclipse中是无法打开的,还是Idea这个工具厉害啊,哈哈!这个源码就不继续深究了,感兴趣的话可以自己看看哈。
private static final boolean saveGeneratedFiles = (Boolean)AccessController.doPrivileged(new GetBooleanAction("sun.misc.ProxyGenerator.saveGeneratedFiles")); 这行代码会读取sun.misc.ProxyGenerator.saveGeneratedFiles属性,如果为true,则会写到磁盘上
public class ProxyGenerator {
//省略了很多成员变量
private static final String superclassName = "java/lang/reflect/Proxy";
private static final String handlerFieldName = "h";
private static final boolean saveGeneratedFiles = (Boolean)AccessController.doPrivileged(new GetBooleanAction("sun.misc.ProxyGenerator.saveGeneratedFiles"));
public static byte[] generateProxyClass(String var0, Class<?>[] var1) {
return generateProxyClass(var0, var1, 49);
}
public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
final byte[] var4 = var3.generateClassFile();
//如果为true则将文件写入磁盘
if (saveGeneratedFiles) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
try {
int var1 = var0.lastIndexOf(46);
Path var2;
if (var1 > 0) {
Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar));
Files.createDirectories(var3);
var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
} else {
var2 = Paths.get(var0 + ".class");
}
//写文件
Files.write(var2, var4, new OpenOption[0]);
return null;
} catch (IOException var4x) {
throw new InternalError("I/O exception saving generated file: " + var4x);
}
}
});
}
return var4;
}
}
八,获取生成的代理类$Proxy0.class文件
第一种方式:System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", true),ProxyGenerator.generateProxyClass方法内部会读取这个变量,如果为true,则会把代理类class文件写到磁盘上,我试了一下没有成功,不知道什么原因。。。。。。
第二种方式:byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{Handle.class})生产代理类class字节数组,然后通过文件流写入磁盘,这个是可以正常写入的。
public class TestJavaDynamicProxy {
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
UserHandle target = new UserHandle();
LogProxyHandle invocationHandler = new LogProxyHandle(target);
// writeProxyClassToHardDisk1();
Handle handle = (Handle) Proxy.newProxyInstance(target.getClass()
.getClassLoader(), target.getClass().getInterfaces(),
invocationHandler);
handle.add();
writeProxyClassToHardDisk2();
}
/**
* 第一种方法,添加这一句是生成代理类的class文件,前提是你需要在工程根目录下创建com/sun/proxy目录
*/
public static void writeProxyClassToHardDisk1() {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", true);
}
/**
* 第二种方法,获取代理类的字节码,然后通过写文件的方式写到磁盘上
*/
public static void writeProxyClassToHardDisk2() {
byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{Handle.class});
FileOutputStream out = null;
try {
out = new FileOutputStream(TestJavaDynamicProxy.class.getResource("").getPath()+"$Proxy0.class");
out.write(classFile);
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我们可以在当前类的.class文件所在目录下看的代理类$Proxy0.class
然后通过JD-JUI对$Proxy0.class进行反编译,可以看到如下源码(省略了equals,toString,hashCode三个方法):
import com.wkp.designpattern.proxy.dynamic.Handle;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
//代理类继承了Proxy,并实现了我们目标类同样实现的Handle接口
public final class $Proxy0 extends Proxy implements Handle
{
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
//构造方法传入的就是我们自己写的InvocationHandler接口的实现类LogProxyHandle的实例,
public $Proxy0(InvocationHandler paramInvocationHandler)
{
//调用父类Proxy中的构造方法
super(paramInvocationHandler);
}
//省略了equals,toString,hashCode三个方法
public final void add()
{
try
{
//h是当前代理类的父类Proxy中定义的成员变量,其实就是LogProxyHandle的实例
this.h.invoke(this, m3, null);
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
static
{
try
{
//通过反射获取方法
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("com.wkp.designpattern.proxy.dynamic.Handle").getMethod("add", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
}
我们可以看下第一步分析时如下的代码,cl.getConstructor(constructorParams)获取的就是$Proxy0类的构造方法,而$Proxy0类的构造方法又会调用Proxy的构造方法,将InvocationHandler的实现类LogProxyHandle的实例引用赋值给Proxy中的成员变量h,所以代理类中的this.h.invoke(this, m3, null)方法的h就是我们实现的LogProxyHandle的实例对象。
protected InvocationHandler h;
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
/** parameter types of a proxy class constructor */
private static final Class<?>[] constructorParams =
{ InvocationHandler.class };
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
//......
Class<?> cl = getProxyClass0(loader, intfs);
//......
final Constructor<?> cons = cl.getConstructor(constructorParams);
//......
return cons.newInstance(new Object[]{h});
}