JDK动态代理源码学习
一、使用示例:
1、定义DTO:
1 public class User { 2 3 private String userName; 4 5 private String passWord; 6 7 private String email; 8 9 public String getUserName() { 10 return userName; 11 } 12 13 public void setUserName(String userName) { 14 this.userName = userName; 15 } 16 17 public String getPassWord() { 18 return passWord; 19 } 20 21 public void setPassWord(String passWord) { 22 this.passWord = passWord; 23 } 24 25 public String getEmail() { 26 return email; 27 } 28 29 public void setEmail(String email) { 30 this.email = email; 31 } 32 }
2、定义接口:
1 public interface UserDao { 2 3 void addUser(User user); 4 }
3、实现接口:
1 public class UserDaoImpl implements UserDao { 2 3 @Override 4 public void addUser(User user) { 5 System.out.println("connect to mySQL dataBase......."); 6 System.out.println("添加用户信息成功..."); 7 } 8 }
4、实现被代理对象的增强类:
1 public class LogHandler implements InvocationHandler { 2 3 private Object target; 4 5 public LogHandler(Object target) { 6 this.target = target; 7 } 8 9 @Override 10 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 11 System.out.println("开始记录日志"); 12 method.invoke(target, args); 13 System.out.println("日志记录完成"); 14 return null; 15 } 16 }
5、调用测试:
1 public static void main(String[] args) { 2 UserDao dao = new UserDaoImpl(); 3 LogHandler handler = new LogHandler(dao); 4 5 UserDao proxy = (UserDao) Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), handler); 6 proxy.addUser(user); 7 }
二、动态生成的代理文件查看:
1、在调用动态代理的main方法中加上:
1 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
2、利用ProxyGenerator生成:
1 public static void main(String[] args) { 2 byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", UserDaoImpl.class.getInterfaces()); 3 String path = "E:\\$Proxy0.class"; 4 try(FileOutputStream fos = new FileOutputStream(path)) { 5 fos.write(classFile); 6 fos.flush(); 7 System.out.println("代理类class文件写入成功"); 8 } catch (Exception e) { 9 System.out.println("写文件错误"); 10 } 11 }
这样在运行代码的时候就会在项目的根目录(或者指定目录)下生成 com.sun.proxy.$ProxyX.class 了,反编译查看:
1 public final class $Proxy0 extends Proxy implements UserDao { 2 private static Method m1; 3 private static Method m2; 4 private static Method m3; 5 private static Method m0; 6 7 public $Proxy0(InvocationHandler var1) throws { 8 super(var1); 9 } 10 11 ...... 12 13 public final void addUser(User var1) throws { 14 try { 15 super.h.invoke(this, m3, new Object[]{var1}); 16 } catch (RuntimeException | Error var3) { 17 throw var3; 18 } catch (Throwable var4) { 19 throw new UndeclaredThrowableException(var4); 20 } 21 } 22 23 static { 24 try { 25 m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object")); 26 m2 = Class.forName("java.lang.Object").getMethod("toString"); 27 m3 = Class.forName("com.ucar.test.service.UserDao").getMethod("addUser", Class.forName("com.ucar.test.dto.User")); 28 m0 = Class.forName("java.lang.Object").getMethod("hashCode"); 29 } catch (NoSuchMethodException var2) { 30 throw new NoSuchMethodError(var2.getMessage()); 31 } catch (ClassNotFoundException var3) { 32 throw new NoClassDefFoundError(var3.getMessage()); 33 } 34 } 35 }
可以看到:
1) 代理类$Proxy0从Proxy派生而来,并且实现了UserDao接口;
2) static块中生成了Object类的三个方法:toString、equals、hashCode,并且也生成了UserDao接口的addUser方法;
3) 调用端通过Proxy.newProxyInstance获取的对象实例也就是这个$Proxy0类型的对象,默认情况下这个类是不保存到磁盘上的,直接在内存中通过ClassLoader加载,因此在断点调试时是无法定位到这个类里面的;
4) 当调用UserDao接口的addUser方法时,其实是调用InvocationHandler.invoke方法,InvocationHandler的实现也就是我们前面实现的LogHandler类,这样就将调用转到LogHandler.invoke方法;
三、源码分析:
1、首先从Proxy.newProxyInstance开始分析:
1 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException{ 2 // null检查,h为null就抛出NullPointerException 3 Objects.requireNonNull(h); 4 // 将接口类对象数组clone一份。 5 final Class<?>[] intfs = interfaces.clone(); 6 7 //执行权限检查 8 final SecurityManager sm = System.getSecurityManager(); 9 if (sm != null) { 10 checkProxyAccess(Reflection.getCallerClass(), loader, intfs); 11 } 12 13 /* 14 * Look up or generate the designated proxy class. 15 */ 16 // 查找或者是生成一个特定的代理类对象 17 Class<?> cl = getProxyClass0(loader, intfs); 18 19 /* 20 * Invoke its constructor with the designated invocation handler. 21 */ 22 try { 23 if (sm != null) { 24 checkNewProxyPermission(Reflection.getCallerClass(), cl); 25 } 26 // 是static final 修饰的,源码: private static final Class<?>[] constructorParams ={ InvocationHandler.class }; 27 // 从代理类对象中查找参数为InvocationHandler的构造器 28 final Constructor<?> cons = cl.getConstructor(constructorParams); 29 final InvocationHandler ih = h; 30 // 检测构造器是否是Public修饰,如果不是则强行转换为可以访问的。 31 if (!Modifier.isPublic(cl.getModifiers())) { 32 AccessController.doPrivileged(new PrivilegedAction<Void>() { 33 public Void run() { 34 cons.setAccessible(true); 35 return null; 36 } 37 }); 38 } 39 // 通过反射,将h作为参数,实例化代理类,返回代理类实例。 40 return cons.newInstance(new Object[]{h}); 41 } catch (IllegalAccessException|InstantiationException e) { 42 throw new InternalError(e.toString(), e); 43 } catch (InvocationTargetException e) { 44 Throwable t = e.getCause(); 45 if (t instanceof RuntimeException) { 46 throw (RuntimeException) t; 47 } else { 48 throw new InternalError(t.toString(), t); 49 } 50 } catch (NoSuchMethodException e) { 51 throw new InternalError(e.toString(), e); 52 } 53 }
这个方法主要工作:
1) getProxyClass0(loader, intfs)方法生成了上面的代理类$Proxy0,生成时主要根据intfs接口获取接口并生成,因此这就是JDK动态代理的类必须要定义接口的愿意;
2) cons.newInstance(new Object[]{h}):利用反射技术实例化代理类,并返回实例化对象;
2、getProxyClass0方法:
1 /** 2 * 生成一个代理类对象, 3 * Generate a proxy class. Must call the checkProxyAccess method 4 * to perform permission checks before calling this. 5 */ 6 private static Class<?> getProxyClass0(ClassLoader loader, 7 Class<?>... interfaces) { 8 // 接口类对象数组不能大于65535个,否则抛出异常 9 if (interfaces.length > 65535) { 10 throw new IllegalArgumentException("interface limit exceeded"); 11 } 12 // 从代理类对象缓存中,根据类加载器和接口类对象数组查找代理类对象, 13 // If the proxy class defined by the given loader implementing 14 // the given interfaces exists, this will simply return the cached copy; 15 // otherwise, it will create the proxy class via the ProxyClassFactory 16 return proxyClassCache.get(loader, interfaces); 17 }
在这个方法中,是直接从一个叫proxyClassCache缓存中读取的,来看一下这个缓存的声明:
1 private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
看一下WeakCache类的大概结构:
1 final class WeakCache<K, P, V> { 2 3 private final ReferenceQueue<K> refQueue= new ReferenceQueue<>(); 4 // the key type is Object for supporting null key 5 // key的类型为Object,支持null key,这里的null key并不是真的可以使用null最为key,而是一个new Objdec()对象实例。ConcurrentHashMap,不允许键或值null,而HashMap可以。ConcurrentHashMap是线程安全的,HashMap不是。 6 private final ConcurrentMap<Supplier<V>, Boolean> reverseMap= new ConcurrentHashMap<>(); 7 8 private final BiFunction<K, P, ?> subKeyFactory; 9 private final BiFunction<K, P, V> valueFactory; 10 11 //构造方法 12 public WeakCache(BiFunction<K, P, ?> subKeyFactory, 13 BiFunction<K, P, V> valueFactory) { 14 this.subKeyFactory = Objects.requireNonNull(subKeyFactory); 15 this.valueFactory = Objects.requireNonNull(valueFactory); 16 } 17 18 19 public V get(K key, P parameter) { 20 //下面会详细介绍这个方法 21 } 22 23 ...... 24 }
3、WeakCache.get方法:
1 // key是类加载器,parameter为接口类对象数组 2 public V get(K key, P parameter) { 3 // 接口类对象数组null检查。 4 Objects.requireNonNull(parameter); 5 6 // 删除过时的条目 7 expungeStaleEntries(); 8 // 生成缓存key对象实例,如果key = null,cacheKey = new Object(); 9 Object cacheKey = CacheKey.valueOf(key, refQueue); 10 11 // lazily install the 2nd level valuesMap for the particular cacheKey 12 // 从缓存map中读取指定cacheKey的缓存数据valuesMap 13 ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); 14 15 if (valuesMap == null) { 16 //如果valuesMap为null,则新增 17 //putIfAbsent方法解释:如果值存在则返回值,并且不对原来的值做任何更改,如果不存在则新增,并返回null 18 //Absent的意思是缺席,不在 19 ConcurrentMap<Object, Supplier<V>> oldValuesMap= map.putIfAbsent(cacheKey,valuesMap = new ConcurrentHashMap<>()); 20 if (oldValuesMap != null) { 21 valuesMap = oldValuesMap; 22 } 23 } 24 25 // create subKey and retrieve the possible Supplier<V> stored by that 26 // subKey from valuesMap 27 // 获取subKey,这里用到了上面提到的Proxy的静态内部类KeyFactory:subKeyFactory.apply(ket,parameter) 28 Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); 29 // 从valuesMap中获取supplier 30 Supplier<V> supplier = valuesMap.get(subKey); 31 Factory factory = null; 32 33 while (true) { 34 if (supplier != null) { 35 // supplier might be a Factory or a CacheValue<V> instance 36 // 4,从工厂中获取代理类对象 37 V value = supplier.get(); 38 if (value != null) { 39 // 5,返回 40 return value; 41 } 42 } 43 // else no supplier in cache 44 // or a supplier that returned null (could be a cleared CacheValue 45 // or a Factory that wasn't successful in installing the CacheValue) 46 47 // lazily construct a Factory 48 if (factory == null) { 49 //1,实例化工厂 50 factory = new Factory(key, parameter, subKey, valuesMap); 51 } 52 53 if (supplier == null) { 54 //2,保存到valuesMap中 55 supplier = valuesMap.putIfAbsent(subKey, factory); 56 if (supplier == null) { 57 // successfully installed Factory 58 // 3,赋值 59 supplier = factory; 60 } 61 // else retry with winning supplier 62 } else { 63 if (valuesMap.replace(subKey, supplier, factory)) { 64 // successfully replaced 65 // cleared CacheEntry / unsuccessful Factory 66 // with our Factory 67 supplier = factory; 68 } else { 69 // retry with current supplier 70 supplier = valuesMap.get(subKey); 71 } 72 } 73 } 74 }
其中supplier就是factory;
4、Factory.get方法:
1 private final class Factory implements Supplier<V> { 2 3 private final K key; 4 private final P parameter; 5 private final Object subKey; 6 private final ConcurrentMap<Object, Supplier<V>> valuesMap; 7 8 Factory(K key, P parameter, Object subKey, 9 ConcurrentMap<Object, Supplier<V>> valuesMap) { 10 this.key = key; 11 this.parameter = parameter; 12 this.subKey = subKey; 13 this.valuesMap = valuesMap; 14 } 15 16 @Override 17 public synchronized V get() { // serialize access 18 // re-check 19 // 检查 20 Supplier<V> supplier = valuesMap.get(subKey); 21 if (supplier != this) { 22 // something changed while we were waiting: 23 // might be that we were replaced by a CacheValue 24 // or were removed because of failure -> 25 // return null to signal WeakCache.get() to retry 26 // the loop 27 return null; 28 } 29 // else still us (supplier == this) 30 31 // create new value 32 V value = null; 33 try { 34 // valueFactory就是WeakCache的valueFactory属性,因为Factory是WeakCache的内部类,所以可以直接访问WeakCache的valueFactory属性 35 value = Objects.requireNonNull(valueFactory.apply(key, parameter)); 36 } finally { 37 if (value == null) { // remove us on failure 38 valuesMap.remove(subKey, this); 39 } 40 } 41 // the only path to reach here is with non-null value 42 assert value != null; 43 44 // wrap value with CacheValue (WeakReference) 45 CacheValue<V> cacheValue = new CacheValue<>(value); 46 47 // try replacing us with CacheValue (this should always succeed) 48 if (valuesMap.replace(subKey, this, cacheValue)) { 49 // put also in reverseMap 50 reverseMap.put(cacheValue, Boolean.TRUE); 51 } else { 52 throw new AssertionError("Should not reach here"); 53 } 54 55 // successfully replaced us with new CacheValue -> return the value 56 // wrapped by it 57 return value; 58 } 59 }
这里最关键的代码:valueFactory.apply(key, parameter);valueFactory就是Proxy的静态内部类ProxyClassFactory;
5、ProxyClassFactory.apply方法:
1 /** 2 * 一个利用给定的类加载器和接口类数组生成,定义并返回代理类对象的工厂方法 3 * A factory function that generates, defines and returns the proxy class given 4 * the ClassLoader and array of interfaces. 5 */ 6 private static final class ProxyClassFactory 7 implements BiFunction<ClassLoader, Class<?>[], Class<?>> 8 { 9 // prefix for all proxy class names 10 // 所有代理类对象的前缀 11 private static final String proxyClassNamePrefix = "$Proxy"; 12 13 // next number to use for generation of unique proxy class names 14 // 用于生成唯一代理类名称的下一个数字 15 private static final AtomicLong nextUniqueNumber = new AtomicLong(); 16 17 @Override 18 public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) { 19 20 Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length); 21 // 22 for (Class<?> intf : interfaces) { 23 /* 24 * Verify that the class loader resolves the name of this 25 * interface to the same Class object. 26 */ 27 Class<?> interfaceClass = null; 28 try { 29 // 加载接口类,获得接口类的类对象,第二个参数为false表示不进行实例化 30 interfaceClass = Class.forName(intf.getName(), false, loader); 31 } catch (ClassNotFoundException e) { 32 } 33 if (interfaceClass != intf) { 34 throw new IllegalArgumentException( 35 intf + " is not visible from class loader"); 36 } 37 /* 38 * Verify that the Class object actually represents an 39 * interface. 40 */ 41 if (!interfaceClass.isInterface()) { 42 throw new IllegalArgumentException( 43 interfaceClass.getName() + " is not an interface"); 44 } 45 /* 46 * Verify that this interface is not a duplicate. 47 */ 48 if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) { 49 throw new IllegalArgumentException( 50 "repeated interface: " + interfaceClass.getName()); 51 } 52 } 53 // package to define proxy class in 54 // 代理类的包名 55 String proxyPkg = null; 56 int accessFlags = Modifier.PUBLIC | Modifier.FINAL; 57 58 /* 59 * Record the package of a non-public proxy interface so that the 60 * proxy class will be defined in the same package. Verify that 61 * all non-public proxy interfaces are in the same package. 62 */ 63 for (Class<?> intf : interfaces) { 64 int flags = intf.getModifiers(); 65 if (!Modifier.isPublic(flags)) { 66 accessFlags = Modifier.FINAL; 67 String name = intf.getName(); 68 int n = name.lastIndexOf('.'); 69 String pkg = ((n == -1) ? "" : name.substring(0, n + 1)); 70 if (proxyPkg == null) { 71 proxyPkg = pkg; 72 } else if (!pkg.equals(proxyPkg)) { 73 throw new IllegalArgumentException( 74 "non-public interfaces from different packages"); 75 } 76 } 77 } 78 79 if (proxyPkg == null) { 80 // if no non-public proxy interfaces, use com.sun.proxy package 81 proxyPkg = com.sun.proxy package 82 proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; 83 } 84 85 /* 86 * 生成代理类的类名 87 * Choose a name for the proxy class to generate. 88 */ 89 long num = nextUniqueNumber.getAndIncrement(); 90 String proxyName = proxyPkg + proxyClassNamePrefix + num; 91 92 /* 93 * Generate the specified proxy class. 94 */ 95 //生成代理类class文件 96 byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags); 97 try { 98 // 返回代理类对象 99 return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); 100 } catch (ClassFormatError e) { 101 /* 102 * A ClassFormatError here means that (barring bugs in the 103 * proxy class generation code) there was some other 104 * invalid aspect of the arguments supplied to the proxy 105 * class creation (such as virtual machine limitations 106 * exceeded). 107 */ 108 throw new IllegalArgumentException(e.toString()); 109 } 110 } 111 } 112 }
这里的ProxyGenerator.generateProxyClass生成了代理类的字节码文件;
6、ProxyGenerator.generateProxyClass方法:
1 public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) { 2 ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2); 3 // 真正用来生成代理类字节码文件的方法在这里 4 final byte[] var4 = var3.generateClassFile(); 5 // 保存代理类的字节码文件 6 if(saveGeneratedFiles) { 7 AccessController.doPrivileged(new PrivilegedAction() { 8 public Void run() { 9 try { 10 int var1 = var0.lastIndexOf(46); 11 Path var2; 12 if(var1 > 0) { 13 Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar), 14 new String[0]); 15 Files.createDirectories(var3, new FileAttribute[0]); 16 var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class"); 17 } else { 18 var2 = Paths.get(var0 + ".class", new String[0]); 19 } 20 21 Files.write(var2, var4, new OpenOption[0]); 22 return null; 23 } catch (IOException var4x) { 24 throw new InternalError("I/O exception saving generated file: " + var4x); 25 } 26 } 27 }); 28 } 29 30 return var4; 31 }
其中generateClassFile是真正用于生成代理类字节码文件的方法;saveGeneratedFiles判断是否要将代理类字节码文件保存到本地磁盘文件,其定义为:
1 private static final boolean saveGeneratedFiles = (Boolean)AccessController.doPrivileged(new GetBooleanAction("sun.misc.ProxyGenerator.saveGeneratedFiles"));
可以看到saveGeneratedFiles是从系统环境变量中读取的”sun.misc.ProxyGenerator.saveGeneratedFiles”变量并转换成布尔类型;
7、generateClassFile方法:
1 private byte[] generateClassFile() { 2 //下面一系列的addProxyMethod方法是将接口中的方法和Object中的方法添加到代理方法中(proxyMethod) 3 this.addProxyMethod(hashCodeMethod, Object.class); 4 this.addProxyMethod(equalsMethod, Object.class); 5 this.addProxyMethod(toStringMethod, Object.class); 6 Class[] var1 = this.interfaces; 7 int var2 = var1.length; 8 9 int var3; 10 Class var4; 11 //获得接口中所有方法并添加到代理方法中 12 for(var3 = 0; var3 < var2; ++var3) { 13 var4 = var1[var3]; 14 Method[] var5 = var4.getMethods(); 15 int var6 = var5.length; 16 17 for(int var7 = 0; var7 < var6; ++var7) { 18 Method var8 = var5[var7]; 19 this.addProxyMethod(var8, var4); 20 } 21 } 22 23 Iterator var11 = this.proxyMethods.values().iterator(); 24 //验证具有相同方法签名的方法的返回类型是否一致 25 List var12; 26 while(var11.hasNext()) { 27 var12 = (List)var11.next(); 28 checkReturnTypes(var12); 29 } 30 31 //后面一系列的步骤用于写代理类Class文件 32 Iterator var15; 33 try { 34 //生成代理类的构造函数 35 this.methods.add(this.generateConstructor()); 36 var11 = this.proxyMethods.values().iterator(); 37 38 while(var11.hasNext()) { 39 var12 = (List)var11.next(); 40 var15 = var12.iterator(); 41 42 while(var15.hasNext()) { 43 ProxyGenerator.ProxyMethod var16 = (ProxyGenerator.ProxyMethod)var15.next(); 44 //将代理类字段声明为Method,并且字段修饰符为 private static. 45 //因为 10 是 ACC_PRIVATE和ACC_STATIC的与运算 故代理类的字段都是 private static Method *** 46 this.fields.add(new ProxyGenerator.FieldInfo(var16.methodFieldName, 47 "Ljava/lang/reflect/Method;", 10)); 48 //生成代理类的方法 49 this.methods.add(var16.generateMethod()); 50 } 51 } 52 //为代理类生成静态代码块对某些字段进行初始化 53 this.methods.add(this.generateStaticInitializer()); 54 } catch (IOException var10) { 55 throw new InternalError("unexpected I/O Exception", var10); 56 } 57 58 if(this.methods.size() > '\uffff') { //代理类中的方法数量超过65535就抛异常 59 throw new IllegalArgumentException("method limit exceeded"); 60 } else if(this.fields.size() > '\uffff') {// 代理类中字段数量超过65535也抛异常 61 throw new IllegalArgumentException("field limit exceeded"); 62 } else { 63 // 后面是对文件进行处理的过程 64 this.cp.getClass(dotToSlash(this.className)); 65 this.cp.getClass("java/lang/reflect/Proxy"); 66 var1 = this.interfaces; 67 var2 = var1.length; 68 69 for(var3 = 0; var3 < var2; ++var3) { 70 var4 = var1[var3]; 71 this.cp.getClass(dotToSlash(var4.getName())); 72 } 73 74 this.cp.setReadOnly(); 75 ByteArrayOutputStream var13 = new ByteArrayOutputStream(); 76 DataOutputStream var14 = new DataOutputStream(var13); 77 78 try { 79 var14.writeInt(-889275714); 80 var14.writeShort(0); 81 var14.writeShort(49); 82 this.cp.write(var14); 83 var14.writeShort(this.accessFlags); 84 var14.writeShort(this.cp.getClass(dotToSlash(this.className))); 85 var14.writeShort(this.cp.getClass("java/lang/reflect/Proxy")); 86 var14.writeShort(this.interfaces.length); 87 Class[] var17 = this.interfaces; 88 int var18 = var17.length; 89 90 for(int var19 = 0; var19 < var18; ++var19) { 91 Class var22 = var17[var19]; 92 var14.writeShort(this.cp.getClass(dotToSlash(var22.getName()))); 93 } 94 95 var14.writeShort(this.fields.size()); 96 var15 = this.fields.iterator(); 97 98 while(var15.hasNext()) { 99 ProxyGenerator.FieldInfo var20 = (ProxyGenerator.FieldInfo)var15.next(); 100 var20.write(var14); 101 } 102 103 var14.writeShort(this.methods.size()); 104 var15 = this.methods.iterator(); 105 106 while(var15.hasNext()) { 107 ProxyGenerator.MethodInfo var21 = (ProxyGenerator.MethodInfo)var15.next(); 108 var21.write(var14); 109 } 110 111 var14.writeShort(0); 112 return var13.toByteArray(); 113 } catch (IOException var9) { 114 throw new InternalError("unexpected I/O Exception", var9); 115 } 116 } 117 }
其中addProxyMethod实现将接口与Object中一些方法添加到代理类中;
8、addProxyMethod:
1 private void addProxyMethod(Method var1, Class<?> var2) { 2 String var3 = var1.getName();//获得方法名称 3 Class[] var4 = var1.getParameterTypes();//获得方法参数类型 4 Class var5 = var1.getReturnType();//获得方法返回类型 5 Class[] var6 = var1.getExceptionTypes();//异常类型 6 String var7 = var3 + getParameterDescriptors(var4);//获得方法签名 7 Object var8 = (List)this.proxyMethods.get(var7);//根据方法前面获得proxyMethod的value 8 if(var8 != null) {//处理多个代理接口中方法重复的情况 9 Iterator var9 = ((List)var8).iterator(); 10 11 while(var9.hasNext()) { 12 ProxyGenerator.ProxyMethod var10 = (ProxyGenerator.ProxyMethod)var9.next(); 13 if(var5 == var10.returnType) { 14 ArrayList var11 = new ArrayList(); 15 collectCompatibleTypes(var6, var10.exceptionTypes, var11); 16 collectCompatibleTypes(var10.exceptionTypes, var6, var11); 17 var10.exceptionTypes = new Class[var11.size()]; 18 var10.exceptionTypes = (Class[])var11.toArray(var10.exceptionTypes); 19 return; 20 } 21 } 22 } else { 23 var8 = new ArrayList(3); 24 this.proxyMethods.put(var7, var8); 25 } 26 27 ((List)var8).add(new ProxyGenerator.ProxyMethod(var3, var4, var5, var6, var2, null)); 28 }
JDK动态代理的原理是根据定义好的规则,用传入的接口创建一个新类,JDK的动态代理只能代理接口中的方法,是针对接口生成代理类。这就是为什么采用动态代理时为什么只能用接口引用指向代理,而不能用传入的类引用执行动态类。
四、参考资料:
https://www.jianshu.com/p/471c80a7e831