java设计模式之 代理模式( 三 )

apply(ClassLoader loader, Class[] interfaces) {Map, 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.* 验证*/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 packageproxyPkg = ReflectUtil.PROXY_PACKAGE + ".";}/** Choose a name for the proxy class to generate.* 这里生成代理类的名称*/long num = nextUniqueNumber.getAndIncrement();// 默认情况下 , 代理类的完全限定名为:com.sun.proxy.$Proxy0 , com.sun.proxy.$Proxy1……依次递增String proxyName = proxyPkg + proxyClassNamePrefix + num;/** Generate the specified proxy class.* 生成指定的代理类 。这里才是真正的生成代理类的字节码的地方*/byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);try {// 根据二进制字节码返回相应的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).*/throw new IllegalArgumentException(e.toString());}}}
真正生产字节码和代理类的是这句byte[]= .( , , );但是没有开源 , 不过我们可以反编译看看:
public static byte[] generateProxyClass(final String var0, Class[] var1, int var2) {ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);final byte[] var4 = var3.generateClassFile();// 这里根据参数配置 , 决定是否把生成的字节码(.class文件)保存到本地磁盘 , 我们可以通过把相应的class文件保存到本地 , 再反编译来看看具体的实现 , 这样更直观if(saveGeneratedFiles) {AccessController.doPrivileged(new PrivilegedAction() {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), new String[0]);Files.createDirectories(var3, new FileAttribute[0]);var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");} else {var2 = Paths.get(var0 + ".class", new String[0]);}Files.write(var2, var4, new OpenOption[0]);return null;} catch (IOException var4x) {throw new InternalError("I/O exception saving generated file: " + var4x);}}});}return var4;}
我们看看的声明final= (().(new ("sun.misc.."))).();