/** * Returns an instance of a proxy class for the specified interfaces * that dispatches method invocations to the specified invocation * handler. * * <p>{@code Proxy.newProxyInstance} throws * {@code IllegalArgumentException} for the same reasons that * {@code Proxy.getProxyClass} does. * * @param loader the class loader to define the proxy class * @param interfaces the list of interfaces for the proxy class * to implement * @param h the invocation handler to dispatch method invocations to * @return a proxy instance with the specified invocation handler of a * proxy class that is defined by the specified class loader * and that implements the specified interfaces * @throws IllegalArgumentException if any of the restrictions on the * parameters that may be passed to {@code getProxyClass} * are violated * @throws SecurityException if a security manager, <em>s</em>, is present * and any of the following conditions is met: * <ul> * <li> the given {@code loader} is {@code null} and * the caller's class loader is not {@code null} and the * invocation of {@link SecurityManager#checkPermission * s.checkPermission} with * {@code RuntimePermission("getClassLoader")} permission * denies access;</li> * <li> for each proxy interface, {@code intf}, * the caller's class loader is not the same as or an * ancestor of the class loader for {@code intf} and * invocation of {@link SecurityManager#checkPackageAccess * s.checkPackageAccess()} denies access to {@code intf};</li> * <li> any of the given proxy interfaces is non-public and the * caller class is not in the same {@linkplain Package runtime package} * as the non-public interface and the invocation of * {@link SecurityManager#checkPermission s.checkPermission} with * {@code ReflectPermission("newProxyInPackage.{package name}")} * permission denies access.</li> * </ul> * @throws NullPointerException if the {@code interfaces} array * argument or any of its elements are {@code null}, or * if the invocation handler, {@code h}, is * {@code null} */ @CallerSensitive publicstatic Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { //如果h为空则抛出异常 Objects.requireNonNull(h);
//拷贝一下接口数组,这里拷贝一下干嘛? final Class<?>[] intfs = interfaces.clone(); //进行一些安全检查,这里不再展开了,与代理实现不太相关 finalSecurityManagersm= System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); }
/* * Look up or generate the designated proxy class. */ //关键方法,产生代理类的Class对象 Class<?> cl = getProxyClass0(loader, intfs);
/* * Invoke its constructor with the designated invocation handler. */ try { if (sm != null) { checkNewProxyPermission(Reflection.getCallerClass(), cl); }
/** * Generate a proxy class. Must call the checkProxyAccess method * to perform permission checks before calling this. */ privatestatic Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { //接口数量不得超过限制,这个限制出自JVM规范 if (interfaces.length > 65535) { thrownewIllegalArgumentException("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
/** * A factory function that generates, defines and returns the proxy class given * the ClassLoader and array of interfaces. */ privatestaticfinalclassProxyClassFactory implementsBiFunction<ClassLoader, Class<?>[], Class<?>> { //prefix for all proxy class names //代理类统一前缀 privatestaticfinalStringproxyClassNamePrefix="$Proxy";
//next number to use for generation of unique proxy class names //代理类计数值,将作为代理类类名的一部分 privatestaticfinalAtomicLongnextUniqueNumber=newAtomicLong();
@Override public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
Map<Class<?>, Boolean> interfaceSet = newIdentityHashMap<>(interfaces.length); for (Class<?> intf : interfaces) { /* * Verify that the class loader resolves the name of this * interface to the same Class object. */ //由于Class对象由全限定名和类加载器共同决定,因此这里判断一下intf的类加载器是否是给定的loader Class<?> interfaceClass = null; try { interfaceClass = Class.forName(intf.getName(), false, loader); } catch (ClassNotFoundException e) { } if (interfaceClass != intf) { thrownewIllegalArgumentException( intf + " is not visible from class loader"); } /* * Verify that the Class object actually represents an * interface. */ //由于JDK 动态代理只能实现接口代理,因此这里校验一下是intf是否为接口 if (!interfaceClass.isInterface()) { thrownewIllegalArgumentException( interfaceClass.getName() + " is not an interface"); } /* * Verify that this interface is not a duplicate. */ //校验一下给定的接口列表是否存在重复 if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) { thrownewIllegalArgumentException( "repeated interface: " + interfaceClass.getName()); } }
//代理类所在的包 StringproxyPkg=null; //package to define proxy class in //代理类的访问权限 intaccessFlags= 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. */ //验证你传入的接口中是否有非public的接口,只要有一个是非public的,那么这些非public的接口都必须在同一个包中 for (Class<?> intf : interfaces) { intflags= intf.getModifiers(); if (!Modifier.isPublic(flags)) { accessFlags = Modifier.FINAL; Stringname= intf.getName(); intn= name.lastIndexOf('.');
//获取完整包名 Stringpkg= ((n == -1) ? "" : name.substring(0, n + 1)); if (proxyPkg == null) { proxyPkg = pkg; } elseif (!pkg.equals(proxyPkg)) { thrownewIllegalArgumentException( "non-public interfaces from different packages"); } } }
if (proxyPkg == null) { //if no non-public proxy interfaces, use com.sun.proxy package //如果接口都是public的,那么代理类的包名就是com.sun.proxy proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; }
/* * Choose a name for the proxy class to generate. */ //当前类名中包含的计数值 longnum= nextUniqueNumber.getAndIncrement();
/* * Generate the specified proxy 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). */ thrownewIllegalArgumentException(e.toString()); } } }
/** * Generate a proxy class given a name and a list of proxy interfaces. */ publicstaticbyte[] generateProxyClass(final String name, Class[] interfaces) { ProxyGeneratorgen=newProxyGenerator(name, interfaces); //生成字节码文件的真正方法 finalbyte[] classFile = gen.generateClassFile();
/** * Generate a class file for the proxy class. This method drives the * class file generation process. */ privatebyte[] generateClassFile() {
/* ============================================================ * Step 1: Assemble ProxyMethod objects for all methods to * generate proxy dispatching code for. */
/* * Record that proxy methods are needed for the hashCode, equals, * and toString methods of java.lang.Object. This is done before * the methods from the proxy interfaces so that the methods from * java.lang.Object take precedence over duplicate methods in the * proxy interfaces. */ //这三个方法将Object的hashcode,equals,toString方法添加到代理方法容器中,代理类除此之外并没有重写Object的其他方法 //除了这三个方法之外,代理类调用Object的其他方法不通过invoke addProxyMethod(hashCodeMethod, Object.class); addProxyMethod(equalsMethod, Object.class); addProxyMethod(toStringMethod, Object.class);
/* * Now record all of the methods from the proxy interfaces, giving * earlier interfaces precedence over later ones with duplicate * methods. */
//获得所有接口中的方法,并将方法添加到代理方法中 for (inti=0; i < interfaces.length; i++) { Method[] methods = interfaces[i].getMethods(); for (intj=0; j < methods.length; j++) { addProxyMethod(methods[j], interfaces[i]); } }
/* * For each set of proxy methods with the same signature, * verify that the methods' return types are compatible. */ for (List<ProxyMethod> sigmethods : proxyMethods.values()) { checkReturnTypes(sigmethods); }
/* ============================================================ * Step 2: Assemble FieldInfo and MethodInfo structs for all of * fields and methods in the class we are generating. */ try { //添加构造方法 methods.add(generateConstructor());
for (List<ProxyMethod> sigmethods : proxyMethods.values()) { for (ProxyMethod pm : sigmethods) {
//add static field for method's Method object fields.add(newFieldInfo(pm.methodFieldName, "Ljava/lang/reflect/Method;", ACC_PRIVATE | ACC_STATIC));
//方法个数不得超过65535 if (methods.size() > 65535) { thrownewIllegalArgumentException("method limit exceeded"); }
//字段个数不得超过65535 if (fields.size() > 65535) { thrownewIllegalArgumentException("field limit exceeded"); }
/* ============================================================ * Step 3: Write the final class file. */
/* * Make sure that constant pool indexes are reserved for the * following items before starting to write the final class file. */ cp.getClass(dotToSlash(className)); cp.getClass(superclassName); for (inti=0; i < interfaces.length; i++) { cp.getClass(dotToSlash(interfaces[i].getName())); }
/* * Disallow new constant pool additions beyond this point, since * we are about to write the final constant pool table. */ cp.setReadOnly();
/** * Add another method to be proxied, either by creating a new * ProxyMethod object or augmenting an old one for a duplicate * method. * <p> * "fromClass" indicates the proxy interface that the method was * found through, which may be different from (a subinterface of) * the method's "declaring class". Note that the first Method * object passed for a given name and descriptor identifies the * Method object (and thus the declaring class) that will be * passed to the invocation handler's "invoke" method for a given * set of duplicate methods. */ privatevoidaddProxyMethod(Method m, Class fromClass) { Stringname= m.getName(); Class[] parameterTypes = m.getParameterTypes(); ClassreturnType= m.getReturnType(); Class[] exceptionTypes = m.getExceptionTypes();
//获取方法签名 Stringsig= name + getParameterDescriptors(parameterTypes);
//找到方法签名对应的方法列表 List<ProxyMethod> sigmethods = proxyMethods.get(sig); //检查方法是否已经存在 if (sigmethods != null) { for (ProxyMethod pm : sigmethods) { if (returnType == pm.returnType) { /* * Found a match: reduce exception types to the * greatest set of exceptions that can thrown * compatibly with the throws clauses of both * overridden methods. */ //方法签名相同的两个方法可能异常列表可能不同,因此需要整合一个最恰当的异常列表 List<Class> legalExceptions = newArrayList<Class>(); collectCompatibleTypes( exceptionTypes, pm.exceptionTypes, legalExceptions); collectCompatibleTypes( pm.exceptionTypes, exceptionTypes, legalExceptions); pm.exceptionTypes = newClass[legalExceptions.size()]; pm.exceptionTypes = legalExceptions.toArray(pm.exceptionTypes); return; } } } else { sigmethods = newArrayList<ProxyMethod>(3); proxyMethods.put(sig, sigmethods); }