Proxy源码分析

1.验证InvocationHandler是否空

2.生成代理类的Class对象,这里戏份比较多,代码中详细注释。

(1).通过类加载器去加载得到Class实例,比较是否想通的Class

(2).判断是否是接口

(3).去重Class,并通过String[]保存接口名

(4).从缓存中创建根据类加载器取得Map,如果没有则创建一个,保存到WeakHashMap

(5). put key,value<一堆接口,正在创建代理的标志> into Map

(6).记录包可见的代理接口,for循环中是校验非公有接口是否在同一包下

(7).生成类名,并生成代理类

(8).把代理类放入代理类缓存

(9).获得有一个InvocationHandler对象参数的构造函数,并创建实例.

 

Java还是外层的东东

Java代码 
  1. package com.alipay.home.proxy;  
  2.   
  3. import java.lang.ref.Reference;  
  4. import java.lang.ref.WeakReference;  
  5. import java.lang.reflect.Constructor;  
  6. import java.lang.reflect.InvocationHandler;  
  7. import java.lang.reflect.InvocationTargetException;  
  8. import java.lang.reflect.Modifier;  
  9. import java.util.Arrays;  
  10. import java.util.Collections;  
  11. import java.util.HashMap;  
  12. import java.util.HashSet;  
  13. import java.util.Map;  
  14. import java.util.Set;  
  15. import java.util.WeakHashMap;  
  16. import sun.misc.ProxyGenerator;  
  17.   
  18. /** 
  19.  * <code>Proxy</code> provides static methods for creating dynamic proxy 
  20.  * classes and instances, and it is also the superclass of all 
  21.  * dynamic proxy classes created by those methods. 
  22.  * 
  23.  * <p>To create a proxy for some interface <code>Foo</code>: 
  24.  * <pre> 
  25.  *     InvocationHandler handler = new MyInvocationHandler(...); 
  26.  *     Class proxyClass = Proxy.getProxyClass( 
  27.  *         Foo.class.getClassLoader(), new Class[] { Foo.class }); 
  28.  *     Foo f = (Foo) proxyClass. 
  29.  *         getConstructor(new Class[] { InvocationHandler.class }). 
  30.  *         newInstance(new Object[] { handler }); 
  31.  * </pre> 
  32.  * or more simply: 
  33.  * <pre> 
  34.  *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), 
  35.  *                                          new Class[] { Foo.class }, 
  36.  *                                          handler); 
  37.  * </pre> 
  38.  * 
  39.  * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy 
  40.  * class</i> below) is a class that implements a list of interfaces 
  41.  * specified at runtime when the class is created, with behavior as 
  42.  * described below. 
  43.  * 
  44.  * A <i>proxy interface</i> is such an interface that is implemented 
  45.  * by a proxy class. 
  46.  * 
  47.  * A <i>proxy instance</i> is an instance of a proxy class. 
  48.  * 
  49.  * Each proxy instance has an associated <i>invocation handler</i> 
  50.  * object, which implements the interface {@link InvocationHandler}. 
  51.  * A method invocation on a proxy instance through one of its proxy 
  52.  * interfaces will be dispatched to the {@link InvocationHandler#invoke 
  53.  * invoke} method of the instance's invocation handler, passing the proxy 
  54.  * instance, a <code>java.lang.reflect.Method</code> object identifying 
  55.  * the method that was invoked, and an array of type <code>Object</code> 
  56.  * containing the arguments.  The invocation handler processes the 
  57.  * encoded method invocation as appropriate and the result that it 
  58.  * returns will be returned as the result of the method invocation on 
  59.  * the proxy instance. 
  60.  * 
  61.  * <p>A proxy class has the following properties: 
  62.  * 
  63.  * <ul> 
  64.  * <li>Proxy classes are public, final, and not abstract. 
  65.  * 
  66.  * <li>The unqualified name of a proxy class is unspecified.  The space 
  67.  * of class names that begin with the string <code>"$Proxy"</code> 
  68.  * should be, however, reserved for proxy classes. 
  69.  * 
  70.  * <li>A proxy class extends <code>java.lang.reflect.Proxy</code>. 
  71.  * 
  72.  * <li>A proxy class implements exactly the interfaces specified at its 
  73.  * creation, in the same order. 
  74.  * 
  75.  * <li>If a proxy class implements a non-public interface, then it will 
  76.  * be defined in the same package as that interface.  Otherwise, the 
  77.  * package of a proxy class is also unspecified.  Note that package 
  78.  * sealing will not prevent a proxy class from being successfully defined 
  79.  * in a particular package at runtime, and neither will classes already 
  80.  * defined by the same class loader and the same package with particular 
  81.  * signers. 
  82.  * 
  83.  * <li>Since a proxy class implements all of the interfaces specified at 
  84.  * its creation, invoking <code>getInterfaces</code> on its 
  85.  * <code>Class</code> object will return an array containing the same 
  86.  * list of interfaces (in the order specified at its creation), invoking 
  87.  * <code>getMethods</code> on its <code>Class</code> object will return 
  88.  * an array of <code>Method</code> objects that include all of the 
  89.  * methods in those interfaces, and invoking <code>getMethod</code> will 
  90.  * find methods in the proxy interfaces as would be expected. 
  91.  * 
  92.  * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will 
  93.  * return true if it is passed a proxy class-- a class returned by 
  94.  * <code>Proxy.getProxyClass</code> or the class of an object returned by 
  95.  * <code>Proxy.newProxyInstance</code>-- and false otherwise. 
  96.  * 
  97.  * <li>The <code>java.security.ProtectionDomain</code> of a proxy class 
  98.  * is the same as that of system classes loaded by the bootstrap class 
  99.  * loader, such as <code>java.lang.Object</code>, because the code for a 
  100.  * proxy class is generated by trusted system code.  This protection 
  101.  * domain will typically be granted 
  102.  * <code>java.security.AllPermission</code>. 
  103.  * 
  104.  * <li>Each proxy class has one public constructor that takes one argument, 
  105.  * an implementation of the interface {@link InvocationHandler}, to set 
  106.  * the invocation handler for a proxy instance.  Rather than having to use 
  107.  * the reflection API to access the public constructor, a proxy instance 
  108.  * can be also be created by calling the {@link Proxy#newProxyInstance 
  109.  * Proxy.newInstance} method, which combines the actions of calling 
  110.  * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the 
  111.  * constructor with an invocation handler. 
  112.  * </ul> 
  113.  * 
  114.  * <p>A proxy instance has the following properties: 
  115.  * 
  116.  * <ul> 
  117.  * <li>Given a proxy instance <code>proxy</code> and one of the 
  118.  * interfaces implemented by its proxy class <code>Foo</code>, the 
  119.  * following expression will return true: 
  120.  * <pre> 
  121.  *     <code>proxy instanceof Foo</code> 
  122.  * </pre> 
  123.  * and the following cast operation will succeed (rather than throwing 
  124.  * a <code>ClassCastException</code>): 
  125.  * <pre> 
  126.  *     <code>(Foo) proxy</code> 
  127.  * </pre> 
  128.  * 
  129.  * <li>Each proxy instance has an associated invocation handler, the one 
  130.  * that was passed to its constructor.  The static 
  131.  * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method 
  132.  * will return the invocation handler associated with the proxy instance 
  133.  * passed as its argument. 
  134.  * 
  135.  * <li>An interface method invocation on a proxy instance will be 
  136.  * encoded and dispatched to the invocation handler's {@link 
  137.  * InvocationHandler#invoke invoke} method as described in the 
  138.  * documentation for that method. 
  139.  * 
  140.  * <li>An invocation of the <code>hashCode</code>, 
  141.  * <code>equals</code>, or <code>toString</code> methods declared in 
  142.  * <code>java.lang.Object</code> on a proxy instance will be encoded and 
  143.  * dispatched to the invocation handler's <code>invoke</code> method in 
  144.  * the same manner as interface method invocations are encoded and 
  145.  * dispatched, as described above.  The declaring class of the 
  146.  * <code>Method</code> object passed to <code>invoke</code> will be 
  147.  * <code>java.lang.Object</code>.  Other public methods of a proxy 
  148.  * instance inherited from <code>java.lang.Object</code> are not 
  149.  * overridden by a proxy class, so invocations of those methods behave 
  150.  * like they do for instances of <code>java.lang.Object</code>. 
  151.  * </ul> 
  152.  * 
  153.  * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3> 
  154.  * 
  155.  * <p>When two or more interfaces of a proxy class contain a method with 
  156.  * the same name and parameter signature, the order of the proxy class's 
  157.  * interfaces becomes significant.  When such a <i>duplicate method</i> 
  158.  * is invoked on a proxy instance, the <code>Method</code> object passed 
  159.  * to the invocation handler will not necessarily be the one whose 
  160.  * declaring class is assignable from the reference type of the interface 
  161.  * that the proxy's method was invoked through.  This limitation exists 
  162.  * because the corresponding method implementation in the generated proxy 
  163.  * class cannot determine which interface it was invoked through. 
  164.  * Therefore, when a duplicate method is invoked on a proxy instance, 
  165.  * the <code>Method</code> object for the method in the foremost interface 
  166.  * that contains the method (either directly or inherited through a 
  167.  * superinterface) in the proxy class's list of interfaces is passed to 
  168.  * the invocation handler's <code>invoke</code> method, regardless of the 
  169.  * reference type through which the method invocation occurred. 
  170.  * 
  171.  * <p>If a proxy interface contains a method with the same name and 
  172.  * parameter signature as the <code>hashCode</code>, <code>equals</code>, 
  173.  * or <code>toString</code> methods of <code>java.lang.Object</code>, 
  174.  * when such a method is invoked on a proxy instance, the 
  175.  * <code>Method</code> object passed to the invocation handler will have 
  176.  * <code>java.lang.Object</code> as its declaring class.  In other words, 
  177.  * the public, non-final methods of <code>java.lang.Object</code> 
  178.  * logically precede all of the proxy interfaces for the determination of 
  179.  * which <code>Method</code> object to pass to the invocation handler. 
  180.  * 
  181.  * <p>Note also that when a duplicate method is dispatched to an 
  182.  * invocation handler, the <code>invoke</code> method may only throw 
  183.  * checked exception types that are assignable to one of the exception 
  184.  * types in the <code>throws</code> clause of the method in <i>all</i> of 
  185.  * the proxy interfaces that it can be invoked through.  If the 
  186.  * <code>invoke</code> method throws a checked exception that is not 
  187.  * assignable to any of the exception types declared by the method in one 
  188.  * of the proxy interfaces that it can be invoked through, then an 
  189.  * unchecked <code>UndeclaredThrowableException</code> will be thrown by 
  190.  * the invocation on the proxy instance.  This restriction means that not 
  191.  * all of the exception types returned by invoking 
  192.  * <code>getExceptionTypes</code> on the <code>Method</code> object 
  193.  * passed to the <code>invoke</code> method can necessarily be thrown 
  194.  * successfully by the <code>invoke</code> method. 
  195.  * 
  196.  * @author  Peter Jones 
  197.  * @version 1.22, 05/11/17 
  198.  * @see     InvocationHandler 
  199.  * @since   1.3 
  200.  */  
  201. public class Proxy implements java.io.Serializable {  
  202.   
  203.     private static final long serialVersionUID = -2222568056686623797L;  
  204.   
  205.     /** prefix for all proxy class names */  
  206.     private final static String proxyClassNamePrefix = "$Proxy";  
  207.   
  208.     /** parameter types of a proxy class constructor */  
  209.     private final static Class[] constructorParams =  
  210.     { InvocationHandler.class };  
  211.   
  212.     /** maps a class loader to the proxy class cache for that loader */  
  213.     private static Map loaderToCache = new WeakHashMap();//弱HashMap  
  214.   
  215.     /** marks that a particular proxy class is currently being generated */  
  216.     private static Object pendingGenerationMarker = new Object();//代理正在被创建的标志!!  
  217.   
  218.     /** next number to use for generation of unique proxy class names */  
  219.     private static long nextUniqueNumber = 0;  
  220.     private static Object nextUniqueNumberLock = new Object();  
  221.   
  222.     /** set of all generated proxy classes, for isProxyClass implementation */  
  223.     private static Map proxyClasses =  
  224.     Collections.synchronizedMap(new WeakHashMap());//线程安全的弱HahsMap  
  225.   
  226.     /** 
  227.      * the invocation handler for this proxy instance. 
  228.      * @serial 
  229.      */  
  230.     protected InvocationHandler h;  
  231.   
  232.     /** 
  233.      * Prohibits instantiation. 
  234.      */  
  235.     private Proxy() {  
  236.     }  
  237.   
  238.     /** 
  239.      * Constructs a new <code>Proxy</code> instance from a subclass 
  240.      * (typically, a dynamic proxy class) with the specified value 
  241.      * for its invocation handler. 
  242.      * 
  243.      * @param   h the invocation handler for this proxy instance 
  244.      */  
  245.     protected Proxy(InvocationHandler h) {  
  246.     this.h = h;  
  247.     }  
  248.   
  249.     /** 
  250.      * Returns the <code>java.lang.Class</code> object for a proxy class 
  251.      * given a class loader and an array of interfaces.  The proxy class 
  252.      * will be defined by the specified class loader and will implement 
  253.      * all of the supplied interfaces.  If a proxy class for the same 
  254.      * permutation of interfaces has already been defined by the class 
  255.      * loader, then the existing proxy class will be returned; otherwise, 
  256.      * a proxy class for those interfaces will be generated dynamically 
  257.      * and defined by the class loader. 
  258.      * 
  259.      * <p>There are several restrictions on the parameters that may be 
  260.      * passed to <code>Proxy.getProxyClass</code>: 
  261.      * 
  262.      * <ul> 
  263.      * <li>All of the <code>Class</code> objects in the 
  264.      * <code>interfaces</code> array must represent interfaces, not 
  265.      * classes or primitive types. 
  266.      * 
  267.      * <li>No two elements in the <code>interfaces</code> array may 
  268.      * refer to identical <code>Class</code> objects. 
  269.      * 
  270.      * <li>All of the interface types must be visible by name through the 
  271.      * specified class loader.  In other words, for class loader 
  272.      * <code>cl</code> and every interface <code>i</code>, the following 
  273.      * expression must be true: 
  274.      * <pre> 
  275.      *     Class.forName(i.getName(), false, cl) == i 
  276.      * </pre> 
  277.      * 
  278.      * <li>All non-public interfaces must be in the same package; 
  279.      * otherwise, it would not be possible for the proxy class to 
  280.      * implement all of the interfaces, regardless of what package it is 
  281.      * defined in. 
  282.      * 
  283.      * <li>For any set of member methods of the specified interfaces 
  284.      * that have the same signature: 
  285.      * <ul> 
  286.      * <li>If the return type of any of the methods is a primitive 
  287.      * type or void, then all of the methods must have that same 
  288.      * return type. 
  289.      * <li>Otherwise, one of the methods must have a return type that 
  290.      * is assignable to all of the return types of the rest of the 
  291.      * methods. 
  292.      * </ul> 
  293.      * 
  294.      * <li>The resulting proxy class must not exceed any limits imposed 
  295.      * on classes by the virtual machine.  For example, the VM may limit 
  296.      * the number of interfaces that a class may implement to 65535; in 
  297.      * that case, the size of the <code>interfaces</code> array must not 
  298.      * exceed 65535. 
  299.      * </ul> 
  300.      * 
  301.      * <p>If any of these restrictions are violated, 
  302.      * <code>Proxy.getProxyClass</code> will throw an 
  303.      * <code>IllegalArgumentException</code>.  If the <code>interfaces</code> 
  304.      * array argument or any of its elements are <code>null</code>, a 
  305.      * <code>NullPointerException</code> will be thrown. 
  306.      * 
  307.      * <p>Note that the order of the specified proxy interfaces is 
  308.      * significant: two requests for a proxy class with the same combination 
  309.      * of interfaces but in a different order will result in two distinct 
  310.      * proxy classes. 
  311.      * 
  312.      * @param   loader the class loader to define the proxy class 
  313.      * @param   interfaces the list of interfaces for the proxy class 
  314.      *      to implement 
  315.      * @return  a proxy class that is defined in the specified class loader 
  316.      *      and that implements the specified interfaces 
  317.      * @throws  IllegalArgumentException if any of the restrictions on the 
  318.      *      parameters that may be passed to <code>getProxyClass</code> 
  319.      *      are violated 
  320.      * @throws  NullPointerException if the <code>interfaces</code> array 
  321.      *      argument or any of its elements are <code>null</code> 
  322.      */  
  323.     public static Class<?> getProxyClass(ClassLoader loader,   
  324.                                          Class<?>... interfaces)  
  325.     throws IllegalArgumentException  
  326.     {//大于65535个接口抛异常  
  327.     if (interfaces.length > 65535) {  
  328.         throw new IllegalArgumentException("interface limit exceeded");  
  329.     }  
  330.   
  331.     Class proxyClass = null;  
  332.   
  333.     /* collect interface names to use as key for proxy class cache */  
  334.     String[] interfaceNames = new String[interfaces.length];//存放接口名  
  335.   
  336.     Set interfaceSet = new HashSet();   // for detecting duplicates//去重复接口的集合  
  337.   
  338.     for (int i = 0; i < interfaces.length; i++) {  
  339.         /* 
  340.          * Verify that the class loader resolves the name of this 
  341.          * interface to the same Class object. 
  342.          * 通过类加载器去加载,验证类实现是否实现接口 
  343.          */  
  344.         String interfaceName = interfaces[i].getName();  
  345.         Class interfaceClass = null;  
  346.         try {  
  347.         //参数false表示类加载器加载时候不解释improt  
  348.         interfaceClass = Class.forName(interfaceName, false, loader);  
  349.         } catch (ClassNotFoundException e) {  
  350.         }  
  351.         if (interfaceClass != interfaces[i]) {  
  352.         throw new IllegalArgumentException(  
  353.             interfaces[i] + " is not visible from class loader");  
  354.         }  
  355.   
  356.         /* 
  357.          * Verify that the Class object actually represents an 
  358.          * interface. 
  359.          * 验证是不是接口 
  360.          */  
  361.         if (!interfaceClass.isInterface()) {  
  362.         throw new IllegalArgumentException(  
  363.             interfaceClass.getName() + " is not an interface");  
  364.         }  
  365.   
  366.         /* 
  367.          * Verify that this interface is not a duplicate. 
  368.          * 去重复 
  369.          */  
  370.         if (interfaceSet.contains(interfaceClass)) {  
  371.         throw new IllegalArgumentException(  
  372.             "repeated interface: " + interfaceClass.getName());  
  373.         }  
  374.         interfaceSet.add(interfaceClass);  
  375.   
  376.         //保存接口名  
  377.         interfaceNames[i] = interfaceName;  
  378.     }  
  379.   
  380.     /* 
  381.      * Using string representations of the proxy interfaces as 
  382.      * keys in the proxy class cache (instead of their Class 
  383.      * objects) is sufficient because we require the proxy 
  384.      * interfaces to be resolvable by name through the supplied 
  385.      * class loader, and it has the advantage that using a string 
  386.      * representation of a class makes for an implicit weak 
  387.      * reference to the class. 
  388.      * 用代理接口的字符串形式表示key存在缓存里尔不是Class对象足够了,因为我们需要 
  389.      * 代理接口去通过类加载器用名字渲染。并且这样带来的好处是使用字符串形式表述class能不明显的依赖class 
  390.      */  
  391.     Object key = Arrays.asList(interfaceNames);  
  392.   
  393.     /* 
  394.      * Find or create the proxy class cache for the class loader. 
  395.      * 从弱HahsMap中取得类加载器,如果不存在,放入弱HashMap 
  396.      */  
  397.     Map cache;  
  398.     synchronized (loaderToCache) {  
  399.         cache = (Map) loaderToCache.get(loader);  
  400.         if (cache == null) {  
  401.         cache = new HashMap();  
  402.         loaderToCache.put(loader, cache);  
  403.         }  
  404.         /* 
  405.          * This mapping will remain valid for the duration of this 
  406.          * method, without further synchronization, because the mapping 
  407.          * will only be removed if the class loader becomes unreachable. 
  408.          */  
  409.     }  
  410.   
  411.     /* 
  412.      * Look up the list of interfaces in the proxy class cache using 
  413.      * the key.  This lookup will result in one of three possible 
  414.      * kinds of values: 
  415.      *     null, if there is currently no proxy class for the list of 
  416.      *         interfaces in the class loader, 
  417.      *     the pendingGenerationMarker object, if a proxy class for the 
  418.      *         list of interfaces is currently being generated, 
  419.      *     or a weak reference to a Class object, if a proxy class for 
  420.      *         the list of interfaces has already been generated. 
  421.      */  
  422.     synchronized (cache) {  
  423.         /* 
  424.          * Note that we need not worry about reaping the cache for 
  425.          * entries with cleared weak references because if a proxy class 
  426.          * has been garbage collected, its class loader will have been 
  427.          * garbage collected as well, so the entire cache will be reaped 
  428.          * from the loaderToCache map. 
  429.          * 注意我们不用担心从缓存中得到已经被清楚的弱引用对应的Class实例(这里弱引用是key,实体是value) 
  430.          * 因为一个代理class会被垃圾回收, 
  431.          * 它的类加载器也会被垃圾回收,所以实体缓存会从loaderToCache map中获得 
  432.          *  
  433.          * 三种情况: 
  434.          * 1如果当前缓存总没有此Proxy类则返回null 
  435.          * 2如果Proxy类正在创建则返回pendingGenerationMarker对象 
  436.          * 3如果此Proxy类已经被创建,则返回WeakReference对象 
  437.          *  
  438.          */  
  439.         do {  
  440.         Object value = cache.get(key);  
  441.         if (value instanceof Reference) {  
  442.             proxyClass = (Class) ((Reference) value).get();  
  443.         }  
  444.         if (proxyClass != null) {  
  445.             // proxy class already generated: return it  
  446.             return proxyClass;  
  447.         } else if (value == pendingGenerationMarker) {  
  448.             // proxy class being generated: wait for it  
  449.             try {  
  450.             cache.wait();  
  451.             } catch (InterruptedException e) {  
  452.             /* 
  453.              * The class generation that we are waiting for should 
  454.              * take a small, bounded time, so we can safely ignore 
  455.              * thread interrupts here. 
  456.              */  
  457.             }  
  458.             continue;  
  459.         } else {  
  460.             /* 
  461.              * No proxy class for this list of interfaces has been 
  462.              * generated or is being generated, so we will go and 
  463.              * generate it now.  Mark it as pending generation. 
  464.              * 没有这堆接口的代理类生成或者正在被创建,我们创建it now!~标记为正在创建,跳出循环 
  465.              */  
  466.             cache.put(key, pendingGenerationMarker);  
  467.             break;  
  468.         }  
  469.         } while (true);  
  470.     }  
  471.   
  472.     try {  
  473.         String proxyPkg = null// package to define proxy class in  
  474.   
  475.         /* 
  476.          * 记录包可见的代理接口,for循环中是校验非公有接口是否在同一包下的算法 
  477.          * Record the package of a non-public proxy interface so that the 
  478.          * proxy class will be defined in the same package.  Verify that 
  479.          * all non-public proxy interfaces are in the same package. 
  480.          */  
  481.         for (int i = 0; i < interfaces.length; i++) {  
  482.         int flags = interfaces[i].getModifiers();  
  483.         if (!Modifier.isPublic(flags)) {  
  484.             String name = interfaces[i].getName();  
  485.             int n = name.lastIndexOf('.');  
  486.             String pkg = ((n == -1) ? "" : name.substring(0, n + 1));  
  487.             if (proxyPkg == null) {  
  488.             proxyPkg = pkg;  
  489.             } else if (!pkg.equals(proxyPkg)) {  
  490.             throw new IllegalArgumentException(  
  491.                 "non-public interfaces from different packages");  
  492.             }  
  493.         }  
  494.         }  
  495.   
  496.         if (proxyPkg == null) { // if no non-public proxy interfaces,  
  497.         proxyPkg = "";      // use the unnamed package  
  498.         }  
  499.   
  500.         {  
  501.         /* 
  502.          * Choose a name for the proxy class to generate. 
  503.          */  
  504.         long num;  
  505.         synchronized (nextUniqueNumberLock) {  
  506.              //这里使用静态属性作为锁,保护了同步区域内的数据  
  507.                //因为num是long型的,无法对原始对象加锁(只能对类加锁)  
  508.                //而如果对整个当前对象加锁会浪费性能  
  509.                //使用一个锁对象,还可达到同时保护多个数据(对象,原始类型)的效果  
  510.             num = nextUniqueNumber++;  
  511.         }  
  512.         String proxyName = proxyPkg + proxyClassNamePrefix + num;//$Proxy+num  
  513.         /* 
  514.          * Verify that the class loader hasn't already 
  515.          * defined a class with the chosen name. 
  516.          */  
  517.   
  518.         /* 
  519.          * Generate the specified proxy class. 
  520.          * //生成Class类的字节码 
  521.          */  
  522.         byte[] proxyClassFile = ProxyGenerator.generateProxyClass(  
  523.             proxyName, interfaces);  
  524.         try {  
  525.             //加载代理类  
  526.             proxyClass = defineClass0(loader, proxyName,  
  527.             proxyClassFile, 0, proxyClassFile.length);  
  528.         } catch (ClassFormatError e) {  
  529.             /* 
  530.              * A ClassFormatError here means that (barring bugs in the 
  531.              * proxy class generation code) there was some other 
  532.              * invalid aspect of the arguments supplied to the proxy 
  533.              * class creation (such as virtual machine limitations 
  534.              * exceeded). 
  535.              */  
  536.             throw new IllegalArgumentException(e.toString());  
  537.         }  
  538.         }  
  539.         // add to set of all generated proxy classes, for isProxyClass  
  540.         proxyClasses.put(proxyClass, null);  
  541.   
  542.     } finally {  
  543.         /* 
  544.          * We must clean up the "pending generation" state of the proxy 
  545.          * class cache entry somehow.  If a proxy class was successfully 
  546.          * generated, store it in the cache (with a weak reference); 
  547.          * otherwise, remove the reserved entry.  In all cases, notify 
  548.          * all waiters on reserved entries in this cache. 
  549.          */  
  550.         synchronized (cache) {  
  551.         if (proxyClass != null) {  
  552.             cache.put(key, new WeakReference(proxyClass));//key是一堆接口的集合,并除去标记正在生成代理的pending generation对象  
  553.         } else {  
  554.             cache.remove(key);  
  555.         }  
  556.         cache.notifyAll();  
  557.         }  
  558.     }  
  559.     return proxyClass;  
  560.     }  
  561.   
  562.     /** 
  563.      * Returns an instance of a proxy class for the specified interfaces 
  564.      * that dispatches method invocations to the specified invocation 
  565.      * handler.  This method is equivalent to: 
  566.      * <pre> 
  567.      *     Proxy.getProxyClass(loader, interfaces). 
  568.      *         getConstructor(new Class[] { InvocationHandler.class }). 
  569.      *         newInstance(new Object[] { handler }); 
  570.      * </pre> 
  571.      * 
  572.      * <p><code>Proxy.newProxyInstance</code> throws 
  573.      * <code>IllegalArgumentException</code> for the same reasons that 
  574.      * <code>Proxy.getProxyClass</code> does. 
  575.      * 
  576.      * @param   loader the class loader to define the proxy class 
  577.      * @param   interfaces the list of interfaces for the proxy class 
  578.      *      to implement 
  579.      * @param   h the invocation handler to dispatch method invocations to 
  580.      * @return  a proxy instance with the specified invocation handler of a 
  581.      *      proxy class that is defined by the specified class loader 
  582.      *      and that implements the specified interfaces 
  583.      * @throws  IllegalArgumentException if any of the restrictions on the 
  584.      *      parameters that may be passed to <code>getProxyClass</code> 
  585.      *      are violated 
  586.      * @throws  NullPointerException if the <code>interfaces</code> array 
  587.      *      argument or any of its elements are <code>null</code>, or 
  588.      *      if the invocation handler, <code>h</code>, is 
  589.      *      <code>null</code> 
  590.      */  
  591.     //类加载器,接口的Class数组,类加载器,通常是APPClassLoader  
  592.     public static Object newProxyInstance(ClassLoader loader,  
  593.                       Class<?>[] interfaces,  
  594.                       InvocationHandler h)  
  595.     throws IllegalArgumentException  
  596.     {  
  597.     if (h == null) {  
  598.         throw new NullPointerException();  
  599.     }  
  600.   
  601.     /* 
  602.      * Look up or generate the designated proxy class. 
  603.      */  
  604.     //生成代理类的Class对象  
  605.     Class cl = getProxyClass(loader, interfaces);  
  606.   
  607.     /* 
  608.      * Invoke its constructor with the designated invocation handler. 
  609.      */  
  610.     try {  
  611.         //获得有一个InvocationHandler对象参数的构造函数  
  612.         Constructor cons = cl.getConstructor(constructorParams);  
  613.         //创建并返回实例  
  614.         return (Object) cons.newInstance(new Object[] { h });  
  615.     } catch (NoSuchMethodException e) {  
  616.         throw new InternalError(e.toString());  
  617.     } catch (IllegalAccessException e) {  
  618.         throw new InternalError(e.toString());  
  619.     } catch (InstantiationException e) {  
  620.         throw new InternalError(e.toString());  
  621.     } catch (InvocationTargetException e) {  
  622.         throw new InternalError(e.toString());  
  623.     }  
  624.     }  
  625.   
  626.     /** 
  627.      * Returns true if and only if the specified class was dynamically 
  628.      * generated to be a proxy class using the <code>getProxyClass</code> 
  629.      * method or the <code>newProxyInstance</code> method. 
  630.      * 
  631.      * <p>The reliability of this method is important for the ability 
  632.      * to use it to make security decisions, so its implementation should 
  633.      * not just test if the class in question extends <code>Proxy</code>. 
  634.      * 
  635.      * @param   cl the class to test 
  636.      * @return  <code>true</code> if the class is a proxy class and 
  637.      *      <code>false</code> otherwise 
  638.      * @throws  NullPointerException if <code>cl</code> is <code>null</code> 
  639.      */  
  640.     public static boolean isProxyClass(Class<?> cl) {  
  641.     if (cl == null) {  
  642.         throw new NullPointerException();  
  643.     }  
  644.   
  645.     return proxyClasses.containsKey(cl);  
  646.     }  
  647.   
  648.     /** 
  649.      * Returns the invocation handler for the specified proxy instance. 
  650.      * 
  651.      * @param   proxy the proxy instance to return the invocation handler for 
  652.      * @return  the invocation handler for the proxy instance 
  653.      * @throws  IllegalArgumentException if the argument is not a 
  654.      *      proxy instance 
  655.      */  
  656.     public static InvocationHandler getInvocationHandler(Object proxy)  
  657.     throws IllegalArgumentException  
  658.     {  
  659.     /* 
  660.      * Verify that the object is actually a proxy instance. 
  661.      */  
  662.     if (!isProxyClass(proxy.getClass())) {  
  663.         throw new IllegalArgumentException("not a proxy instance");  
  664.     }  
  665.   
  666.     Proxy p = (Proxy) proxy;  
  667.     return p.h;  
  668.     }  
  669.   
  670.     private static native Class defineClass0(ClassLoader loader, String name,  
  671.                          byte[] b, int off, int len);  
  672. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值