⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxy.java

📁 JAVA基本类源代码,大家可以学习学习!
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    public static Class getProxyClass(ClassLoader loader, 				      Class[] interfaces)	throws IllegalArgumentException    {	Class proxyClass = null;	/* buffer to generate string key for proxy class cache */	StringBuffer keyBuffer = new StringBuffer();	for (int i = 0; i < interfaces.length; i++) {	    /*	     * Verify that the class loader resolves the name of this	     * interface to the same Class object.	     */	    Class interfaceClass = null;	    try {		interfaceClass =		    Class.forName(interfaces[i].getName(), false, loader);	    } catch (ClassNotFoundException e) {	    }	    if (interfaceClass != interfaces[i]) {		throw new IllegalArgumentException(		    interfaces[i] + " 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");	    }	    // continue building string key for proxy class cache	    keyBuffer.append(interfaces[i].getName()).append(';');	}	/*	 * Using a string representation of the proxy interfaces as keys	 * in the proxy class cache instead of a collection of their Class	 * objects is sufficiently correct because we require the proxy	 * interfaces to be resolvable by name through the supplied class	 * loader, and it has a couple of advantages: matching String	 * objects is simpler and faster than matching collections of	 * objects, and using a string representation of a class makes	 * for an implicit weak reference to the class.	 */	String key = keyBuffer.toString();	/*	 * Find or create the proxy class cache for the class loader.	 */	Map cache;	synchronized (loaderToCache) {	    cache = (Map) loaderToCache.get(loader);	    if (cache == null) {		cache = new HashMap(3);		loaderToCache.put(loader, cache);	    }	    /*	     * This mapping will remain valid for the duration of this	     * method, without further synchronization, because the mapping	     * will only be removed if the class loader becomes unreachable.	     */	}	/*	 * Look up the list of interfaces in the proxy class cache using	 * the string key.  This lookup will result in one of three possible	 * kinds of values:	 *     null, if there is currently no proxy class for the list of	 *         interfaces in the class loader,	 *     the pendingGenerationMarker object, if a proxy class for the	 *         list of interfaces is currently being generated,	 *     or a weak reference to a Class object, if a proxy class for	 *         the list of interfaces has already been generated.	 */	synchronized (cache) {	    /*	     * Note that we need not worry about reaping the cache for	     * entries with cleared weak references because if a proxy class	     * has been garbage collected, its class loader will have been	     * garbage collected as well, so the entire cache will be reaped	     * from the loaderToCache map.	     */	    do {		Object value = cache.get(key);		if (value instanceof Reference) {		    proxyClass = (Class) ((Reference) value).get();		}		if (proxyClass != null) {		    // proxy class already generated: return it		    return proxyClass;		} else if (value == pendingGenerationMarker) {		    // proxy class being generated: wait for it		    try {			cache.wait();		    } catch (InterruptedException e) {			/*			 * The class generation that we are waiting for should			 * take a small, bounded time, so we can safely ignore			 * thread interrupts here.			 */		    }		    continue;		} else {		    /*		     * No proxy class for this list of interfaces has been		     * generated or is being generated, so we will go and		     * generate it now.  Mark it as pending generation.		     */		    cache.put(key, pendingGenerationMarker);		    break;		}	    } while (true);	}	try {	    String proxyPkg = null;	// package to define proxy class in	    /*	     * 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 (int i = 0; i < interfaces.length; i++) {		int flags = interfaces[i].getModifiers();		if (!Modifier.isPublic(flags)) {		    String name = interfaces[i].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,		proxyPkg = "";		// use the unnamed package	    }	    {		/*		 * Choose a name for the proxy class to generate.		 */		long num;		synchronized (nextUniqueNumberLock) {		    num = nextUniqueNumber++;		}		String proxyName = proxyPkg + proxyClassNamePrefix + num;		/*		 * Verify that the class loader hasn't already		 * defined a class with the chosen name.		 */		/*		 * Generate the specified proxy class.		 */		byte[] proxyClassFile =	ProxyGenerator.generateProxyClass(		    proxyName, interfaces);		try {		    proxyClass = 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());		}	    }	    // add to set of all generated proxy classes, for isProxyClass	    proxyClasses.put(proxyClass, null);	} finally {	    /*	     * We must clean up the "pending generation" state of the proxy	     * class cache entry somehow.  If a proxy class was successfully	     * generated, store it in the cache (with a weak reference);	     * otherwise, remove the reserved entry.  In all cases, notify	     * all waiters on reserved entries in this cache.	     */	    synchronized (cache) {		if (proxyClass != null) {		    cache.put(key, new WeakReference(proxyClass));		} else {		    cache.remove(key);		}		cache.notifyAll();	    }	}	return proxyClass;    }    /**     * Returns an instance of a proxy class for the specified interfaces     * that dispatches method invocations to the specified invocation     * handler.  This method is equivalent to:     * <pre>     *     Proxy.getProxyClass(loader, interfaces).     *         getConstructor(new Class[] { InvocationHandler.class }).     *         newInstance(new Object[] { handler });     * </pre>     *     * <p><code>Proxy.newProxyInstance</code> throws     * <code>IllegalArgumentException</code> for the same reasons that     * <code>Proxy.getProxyClass</code> 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</code>     *		are violated     * @throws	NullPointerException if the <code>interfaces</code> array     *		argument or any of its elements are <code>null</code>, or     *		if the invocation handler, <code>h</code>, is     *		<code>null</code>     */    public static Object newProxyInstance(ClassLoader loader,					  Class[] interfaces,					  InvocationHandler h)	throws IllegalArgumentException    {	if (h == null) {	    throw new NullPointerException();	}	/*	 * Look up or generate the designated proxy class.	 */	Class cl = getProxyClass(loader, interfaces);	/*	 * Invoke its constructor with the designated invocation handler.	 */	try {	    Constructor cons = cl.getConstructor(constructorParams);	    return (Object) cons.newInstance(new Object[] { h });	} catch (NoSuchMethodException e) {	    throw new InternalError(e.toString());	} catch (IllegalAccessException e) {	    throw new InternalError(e.toString());	} catch (InstantiationException e) {	    throw new InternalError(e.toString());	} catch (InvocationTargetException e) {	    throw new InternalError(e.toString());	}    }    /**     * Returns true if and only if the specified class was dynamically     * generated to be a proxy class using the <code>getProxyClass</code>     * method or the <code>newProxyInstance</code> method.     *     * <p>The reliability of this method is important for the ability     * to use it to make security decisions, so its implementation should     * not just test if the class in question extends <code>Proxy</code>.     *     * @param	cl the class to test     * @return  <code>true</code> if the class is a proxy class and     *		<code>false</code> otherwise     * @throws	NullPointerException if <code>cl</code> is <code>null</code>     */    public static boolean isProxyClass(Class cl) {	if (cl == null) {	    throw new NullPointerException();	}	return proxyClasses.containsKey(cl);    }    /**     * Returns the invocation handler for the specified proxy instance.     *     * @param	proxy the proxy instance to return the invocation handler for     * @return	the invocation handler for the proxy instance     * @throws	IllegalArgumentException if the argument is not a     *		proxy instance     */    public static InvocationHandler getInvocationHandler(Object proxy)	throws IllegalArgumentException    {	/*	 * Verify that the object is actually a proxy instance.	 */	if (!isProxyClass(proxy.getClass())) {	    throw new IllegalArgumentException("not a proxy instance");	}	Proxy p = (Proxy) proxy;	return p.h;    }    private static native Class defineClass0(ClassLoader loader, String name,					     byte[] b, int off, int len);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -