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) 代理类$Proxy0Proxy派生而来,并且实现了UserDao接口;

2) static块中生成了Object类的三个方法:toStringequalshashCode,并且也生成了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

https://blog.csdn.net/u012834750/article/details/82499648

https://www.cnblogs.com/zhangchengzi/p/9713807.html

posted on 2019-07-02 17:27  小夏coding  阅读(173)  评论(0编辑  收藏  举报

导航