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. * 具体的获取代理类Class对象调用方法,传入classloder和接口类也就是上面的Subject */ Class<?> cl = getProxyClass0(loader, intfs);
/* * Invoke its constructor with the designated invocation handler. */ try { if (sm != null) { checkNewProxyPermission(Reflection.getCallerClass(), cl); } //反射获取构造方法 final Constructor<?> cons = cl.getConstructor(constructorParams); //一句没用的代码,ih都没有用 final InvocationHandler ih = h; //反射设置访问权限 if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run(){ cons.setAccessible(true); returnnull; } }); } //通过反射调用构造方法直接返回实例对象,h是我们的传入的InvocationHandler实例。 //这里是动态生成是实现Subject接口的代理类,后面我会给大家看看这个类里面的东东 return cons.newInstance(new Object[]{h}); } catch (IllegalAccessException|InstantiationException e) { thrownew InternalError(e.toString(), e); } catch (InvocationTargetException e) { Throwable t = e.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { thrownew InternalError(t.toString(), t); } } catch (NoSuchMethodException e) { thrownew InternalError(e.toString(), e); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/** * Generate a proxy class. Must call the checkProxyAccess method * to perform permission checks before calling this. * 动态生成代理类Class对象调用方法 */ privatestatic Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { //接口类数组的长度小于65535,65535是计算机16位二进制最大数,如果大于就会内存溢出. if (interfaces.length > 65535) { thrownew 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 //调用get方法,这里proxyClassCache对象是一个WeakCache(弱引用,用作缓存)对象。具体的get看下面。 return proxyClassCache.get(loader, interfaces); }
// lazily install the 2nd level valuesMap for the particular cacheKey //第一次进来才初始化valuseMap保存代理类和代理的接口 ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); if (valuesMap == null) { ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>()); if (oldValuesMap != null) { valuesMap = oldValuesMap; } }
// create subKey and retrieve the possible Supplier<V> stored by that // subKey from valuesMap //这一步获取代理类,调用BiFunction.apply方法,具体看下面 Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); //从valuesMap中获取代理类,第一次或者新的classloder肯定为空 Supplier<V> supplier = valuesMap.get(subKey); Factory factory = null;
while (true) { //不为空的话直接取出来返回 if (supplier != null) { // supplier might be a Factory or a CacheValue<V> instance V value = supplier.get(); if (value != null) { 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 if (factory == null) { factory = new Factory(key, parameter, subKey, valuesMap); } //为空的时候将上面生成的代理类放到valuesMap中 if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { // successfully installed Factory supplier = factory; } // else retry with winning supplier } else { 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); } } } }
@Override public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) { //IdentityHashMap是一个key可以重复的的Map,这里jdk当做set来用 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) { thrownew IllegalArgumentException( intf + " is not visible from class loader"); } /* * Verify that the Class object actually represents an * interface. * 验证是否为接口 jdk动态代理只能代理接口 */ if (!interfaceClass.isInterface()) { thrownew IllegalArgumentException( interfaceClass.getName() + " is not an interface"); } /* * Verify that this interface is not a duplicate. */ //将interfaceClass放入到interfaceSet,这里interfaceSet是IdentityHashMap //当我们put的时候发现已经有key了会添加后返回这个以前的key对应的value值, //这里来判读interface是否重复。 if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) { thrownew 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; } elseif (!pkg.equals(proxyPkg)) { thrownew IllegalArgumentException( "non-public interfaces from different packages"); } } }
if (proxyPkg == null) { // if no non-public proxy interfaces, use com.sun.proxy package //无非公有接口则默认为com.sun.proxy package proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; }
/* * Choose a name for the proxy class to generate. * 选择一个代理类名称 第一为$Proxy0 以后类推。num生成是线程安全的 */ long num = nextUniqueNumber.getAndIncrement(); String proxyName = proxyPkg + proxyClassNamePrefix + num;
/* * Generate the specified proxy class. * 生成class二进制文件,具体看下面 */ byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); try { //这个方法是native方法,加载class二进制 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). */ thrownew IllegalArgumentException(e.toString()); } } }
从中我们可以看出动态生成的代理类是以$Proxy为类名前缀,继承自Proxy,并且实现了Proxy.newProxyInstance(…)第二个参数传入的所有接口的类。如果代理类实现的接口中存在非 public 接口,则其包名为该接口的包名,否则为com.sun.proxy。其中的dealTeask()函数都是直接交给h去处理,h在父类Proxy中定义为protected InvocationHandler h;即为Proxy.newProxyInstance(…)第三个参数。所以InvocationHandler的子类 C 连接代理类 A 和委托类 B,它是代理类 A 的委托类,委托类 B 的代理类。
小结一下
本想仔细分析一下 generateClassFile 的实现,但直接生成 class 文件这种方式确实较为复杂,我就简单说一下其原理吧。有一种比较土的生成 class 文件的方法就是直接使用源码的字符串,用 JavaCompiler 动态编译生成。这样就可以通过所需实现的接口运用反射获得其方法信息,方法实现则直接调用 InvocationHandler 实现类的 invoke 方法,拼出整个代理类的源码,编译生成。而直接组装 class 文件的这种方式更为直接,根据 JVM 规范所定义的 class 文件的格式,省去了组装源码的步骤,使用输出流直接按格式生成 class 文件,相当于自己实现了 JVM 的功能。这样生成 class 后通过 classloader 加载类,反射调用构造方法进行实例化,就可以得到代理类对象了。上面的代码(还有一部分没贴)就是组装 class 文件的过程,奈何我对其也不是很懂