我们以几个问题,来开始我们今天的学习,如果下面几个问题,你都能说出个一二,那么恭喜你,你已经掌握了这方面的知识。
1,什么是代理模式?
2,Java中,静态代理与动态代理的区别?
3,Spring使用的是JDK的动态代理,还是CGLIB的动态代理?
4,JDK的动态代理的实现原理?
5,JDK的动态代理与CGLIB的动态代理的实现上,有何不同?
6,你知道的,还有其他动态代理技术吗?请简述实现原理。
OK,言归正传。
Java的代理模式分为:静态代理和动态代理。首先我们需要搞清楚,什么是代理模式?注意,我们这里说的是JDK的代理模式。代理模式中,代
理类和委托类具有相同的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间
通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,
来提供特定的服务。
说白了,JDK的代理模式,提供了另一种生成对象的方式。从程序结构上来说,JDK的代理模式,把代理类作为对象,代理代理类完成基本的功能,
并且增加了其他行为,我们可以在代理类执行之前(后),插入一段代码,完成其他的附加功能。我们可以把这种模式,看做是对生成对象的一种控制,
或者说是一种管理。Spring管理bean使用的就是动态代理。
代理模式是23种设计模式之一,我们来回顾一下23种设计模式:
Factory(工厂模式)
Builder(建造模式)
Factory Method(工厂方法模式)
Prototype(原始模型模式)
Singleton(单例模式)
Facade(门面模式)
Adapter(适配器模式)
Bridge(桥梁模式)
Composite(合成模式)
Decorator(装饰模式)
Flyweight(享元模式)
Proxy(代理模式)
Command(命令模式)
Interpreter(解释器模式)
Visitor(访问者模式)
Iterator(迭代子模式)
Mediator(调停者模式)
Memento(备忘录模式)
Observer(观察者模式)
State(状态模式)
Strategy(策略模式)
Template Method(模板方法模式)
Chain Of Responsibleity(责任链模式)
按照代理的创建时期,代理类可以分为:静态代理和动态代理。静态代理指的是,由程序员创建或特定工具自动生成源代码,再对其进行编译。
在程序运行前,代理类的.class文件就已经存在了。动态代理指的是,在程序运行时,运用反射机制动态生成源代码,再对其进行编译。
只看概念,比较抽象,我们下面来看一下代码示例。我们先来看一下静态代理的组成要素:
* 一个接口
* 一个接口实现类
* 一个代理类,也实现了接口,是增强版的实现类
/** * @description 代理模式 之 静态代理 -- StaticProxyInterface接口 * @description 一个接口 */ public interface StaticProxyInterface { public void queryInfo(); }
/** * @description 代理模式 之 静态代理 -- StaticProxyImpl实现类 * @description StaticProxyImpl,在代理模式中,叫做委托类,包含业务逻辑 * @description 一个接口实现类 */ public class StaticProxyImpl implements StaticProxyInterface{ public void queryInfo() { System.out.println("代理模式 之 静态代理 -- StaticProxyImpl实现类 查看信息..."); } }
/** * @description 代理模式 之 静态代理 -- StaticProxy代理类 * @description StaticProxy,在代理模式中,叫做代理类,增强StaticProxyImpl实现类 * @description 一个代理类,也实现了接口,是增强版的实现类 */ public class StaticProxy implements StaticProxyInterface{ private StaticProxyImpl staticProxyImpl; public StaticProxy(StaticProxyImpl staticProxyImpl){ this.staticProxyImpl = staticProxyImpl; } public void queryInfo() { // 事务处理之前,可以执行一段代码 System.out.println("事务处理之前..."); // 调用委托类的方法 staticProxyImpl.queryInfo(); // 事务处理之后,可以执行一段代码 System.out.println("事务处理之后..."); } }
/** * @description 代理模式 之 静态代理 * @description 测试类StaticProxyTest * @description 什么是静态代理:静态代理指的是,由程序员创建或特定工具自动生成源代码,再对其进行编译。 * 在程序运行前,代理类的.class文件就已经存在了。 * @description 静态代理组成要素: * 1,一个接口 * 2,一个接口实现类 * 3,一个代理类,也实现接口,是增强版的接口实现类 */ public class StaticProxyTest { public static void main(String[] args){ StaticProxyImpl staticProxyImpl = new StaticProxyImpl(); StaticProxy staticProxy = new StaticProxy(staticProxyImpl); staticProxy.queryInfo(); } /* * 静态代理的一个缺点就是:我们需要为每一个接口生成一个代理类,也就是一个接口必然要对应一个代理类。这样 * 必然会生成很多的代理类,并且这些代理类的代码有很多重复的部分。解决这一问题,最好的办法就是通过一个代理类 * 完成全部的代理功能,此时就要使用动态代理。 */ }
动态代理又可以分为2种:JDK的动态代理和CGLIB的动态代理,JDK的动态代理依赖具体的接口,需要绑定接口,如果一个类没有实现接口,
则不能使用JDK的动态代理。CGLIB的动态代理不依赖具体的接口,功能更加强大。下面我们分别进行说明,JDK的动态代理的关键是
InvocationHandler接口,先来看JDK的动态代理:
/** * @description 代理模式 之 JDK的动态代理 -- DynamicProxyInterface接口 * @description 一个接口 */ public interface DynamicProxyInterface { public void queryInfo(); }
/** * @description 代理模式 之 JDK的动态代理 -- DynamicProxyImpl实现类 * @description DynamicProxyImpl,在代理模式中,叫做委托类,包含业务逻辑 * @description 一个接口实现类 */ public class DynamicProxyImpl implements DynamicProxyInterface { public void queryInfo() { // TODO Auto-generated method stub System.out.println("代理模式 之 JDK的动态代理 -- DynamicProxyImpl实现类 查看信息..."); } }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @description 代理模式 之 JDK的动态代理 -- DynamicProxy代理类 * @description DynamicProxy,在代理模式中,叫做代理类,增强DynamicProxyImpl实现类 * @description 一个代理类,实现了InvocationHandler接口 * @description JDK的动态代理 与 静态代理的区别就在这个代理类,静态代理类直接实现接口,而JDK的动态代理类不 * 直接实现具体的接口,而是实现了JDK提供的InvocationHandler接口。 */ public class DynamicProxy implements InvocationHandler { // 目标实现类,也就是某个接口的实现类,这里的target_interface_implements,可以看做是一种抽象 private Object target_interface_implements; // 带参数构造方法,把目标实现类的对象作为参数传递进去,这里不是覆盖具体某个实现类的构造方法,而是抽象出来一个方法 public Object dynamicBindImplToProxyClass(Object target_interface_implements){ this.target_interface_implements = target_interface_implements; // 取得代理对象 return Proxy.newProxyInstance(target_interface_implements.getClass().getClassLoader(), target_interface_implements.getClass().getInterfaces(), this); // JDK的动态代理依赖具体的接口,需要绑定接口,如果一个类没有实现接口,则不能使用JDK的动态代理 } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object result = null; // 事务处理之前,可以执行一段代码 System.out.println("事务处理之前..."); // 执行方法 result = method.invoke(target_interface_implements, args); // 事务处理之后,可以执行一段代码 System.out.println("事务处理之后..."); return result; } }
package com.ebank.action; /** * @description 代理模式 之 JDK的动态代理 * @description 测试类DynamicProxyTest * @description 动态代理指的是,在程序运行时,运用反射机制动态生成源代码,再对其进行编译。 * @description JDK的动态代理组成要素: * 1,一个接口 * 2,一个接口实现类 * 3,一个代理类,实现了InvocationHandler接口 */ public class DynamicProxyTest { public static void main(String[] args){ DynamicProxy dynamicProxy = new DynamicProxy(); DynamicProxyInterface dynamicProxyForImpl = (DynamicProxyInterface) dynamicProxy.dynamicBindImplToProxyClass(new DynamicProxyImpl()); dynamicProxyForImpl.queryInfo(); } /* * JDK的动态代理依靠具体的接口,如果有些类并没有实现,则不能使用JDK的动态代理,这时候就需要 * 使用CGLIB的动态代理 * // JDK的动态代理的关键是InvocationHandler接口 */ }
接下来我们来分析一下JDK的动态代理的实现原理,JDK实现的动态代理,我们可以狭义的理解为,通过实现InvocationHandler接口,而实现的
动态代理。JDK的动态代理的实现需要依赖接口。拿上面的JDK的动态代理的示例代码来说,DynamicProxyImpl这个类,必须要实现某个接口,才
能借助InvocationHandler来实现动态代理,因为Proxy.newProxyInstance()这个方法中,需要传入代理类的接口作为参数。在示例中,我们的
DynamicProxyImpl类实现了DynamicProxyInterface接口。我们实现首先来看InvocationHandler接口的源代码:
package java.lang.reflect; public interface InvocationHandler { /** * Processes a method invocation on a proxy instance and returns the result. This method will be invoked on an invocation * handler when a method is invoked on a proxy instance that it is associated with. * Processes : 处理,加工,审核 * @param proxy--the proxy instance that the method was invoked on * * @param method--the Method instance corresponding to the interface method invoked on the proxy instance. The declaring * class of the Method object will be the interface that the method was declared in, which may be a * superinterface of the proxy interface that the proxy class inherits the method through. * * @param args--an array of objects containing the values of the arguments passed in the method invocation on the proxy * instance, or null if interface method takes no arguments.Arguments of primitive types are wrapped in instances of the * appropriate primitive wrapper class, such as Integer or Boolean. * primitive : 简单的,这里个人理解为基本的,primitive type 意为基本数据类型 * @return the value to return from the method invocation on the proxy instance. If the declared return type of the interface * method is a primitive type, then the value returned by this method must be an instance of the corresponding primitive * wrapper class; otherwise, it must be a type assignable to the declared return type. If the value returned by this method is * null and the interface method's return type is primitive, then a NullPointerException will be * thrown by the method invocation on the proxy instance. If the value returned by this method is otherwise not compatible with * the interface method's declared return type as described above, a ClassCastException will be thrown by the method * invocation on the proxy instance. */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }
然后,我们来看CGLIB的动态代理,CGLIB的动态代理的关键是MethodInterceptor接口,这个接口位于:net.sf.cglib.proxy.MethodInterceptor
/** * @description 代理模式 之 CGLIB的动态代理 -- CglibDynamicProxyImpl类 * @description CglibDynamicProxyImpl,在代理模式中,叫做委托类,包含业务逻辑 * @description 一个没有实现接口的类 */ public class CglibDynamicProxyImpl { public void queryInfo() { // TODO Auto-generated method stub System.out.println("代理模式 之 CGLIB的动态代理 -- CglibDynamicProxyImpl类 查看信息..."); } }
import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * @description 代理模式 之 CGLIB的动态代理 -- CglibDynamicProxy代理类 * @description CglibDynamicProxy,在代理模式中,叫做代理类,增强DynamicProxyImpl实现类 * @description 一个代理类,实现了MethodInterceptor接口 * @description CGLIB的动态代理 与 静态代理的区别就在这个代理类,静态代理类直接实现接口,而CGLIB的动态代理类不 * 直接实现具体的接口,而是实现了MethodInterceptor接口。 */ public class CglibDynamicProxy implements MethodInterceptor { // 目标实现类,也就是某个接口的实现类,这里的target_interface_implements,可以看做是一种抽象 private Object target_class; // 创建代理对象 public Object getInstance(Object target_class){ this.target_class = target_class; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target_class.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } // 回调方法 public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy proxy) throws Throwable { // 事务处理之前,可以执行一段代码 System.out.println("事务处理之前..."); // 执行方法 proxy.invokeSuper(arg0, arg2); // 事务处理之后,可以执行一段代码 System.out.println("事务处理之后..."); return null; } }
/** * @description 代理模式 之 CGLIB的动态代理 * @description 测试类CglibDynamicProxyTest * @description 动态代理指的是,在程序运行时,运用反射机制动态生成源代码,再对其进行编译。 * @description CGLIB的动态代理组成要素: * 1,一个类 * 2,一个代理类,实现了MethodInterceptor接口 */ public class CglibDynamicProxyTest { public static void main(String[] args){ CglibDynamicProxy cglibDynamicProxy = new CglibDynamicProxy(); CglibDynamicProxyImpl cglibDynamicProxyImpl = (CglibDynamicProxyImpl) cglibDynamicProxy.getInstance(new CglibDynamicProxyImpl()); cglibDynamicProxyImpl.queryInfo(); } // CGLIB的动态代理的关键是MethodInterceptor接口 }
CGLIB实现的动态代理,要求委托类不能被final关键字修饰,因为在运行期间,通过Java的反射机制,会生成委托类的子类。我们都知道,一个
类,一旦被final关键字修饰,那么这个类就不能被继承。假如我们使用final关键字修饰了委托类,编译期间不会报错,但是程序运行时,会报错:
不能继承final类,如下:
- Exception in thread "main" java.lang.IllegalArgumentException: Cannot subclass final class class com.yangcq.CglibDynamicProxyImpl
- at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
- at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
- at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
- at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
- at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
- at com.ebank.action.CglibDynamicProxy.getInstance(CglibDynamicProxy.java:24)
- at com.ebank.action.CglibDynamicProxyTest.main(CglibDynamicProxyTest.java:14)
CGLIB的动态代理的实现原理是什么样的呢?CGLIB为我们提供了MethodInterceptor接口,我们不需要依赖某个接口,也就是说,即使代理类没有
实现任何接口,也是可以借助CGLIB来实现动态代理的。CGLIB是借助Java反射机制,在运行期间为代理类生成一个子类,通过子类,来完成父类的动
态代理。下面我们来看一下MethodInterceptor的源代码:
package net.sf.cglib.proxy; import java.lang.reflect.Method; public abstract interface MethodInterceptor extends Callback{ public abstract Object intercept(Object paramObject, Method paramMethod, Object[] paramArrayOfObject, MethodProxy paramMethodProxy) throws Throwable; }
实现动态代理,我们需要关注一个关键的类:public class Proxy implements java.io.Serializable
Proxy的源代码:
package java.lang.reflect; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; import sun.misc.ProxyGenerator; public class Proxy implements java.io.Serializable { private static final long serialVersionUID = -2222568056686623797L; private final static String proxyClassNamePrefix = "$Proxy"; private final static Class[] constructorParams = { InvocationHandler.class }; private static Map loaderToCache = new WeakHashMap(); private static Object pendingGenerationMarker = new Object(); private static long nextUniqueNumber = 0; private static Object nextUniqueNumberLock = new Object(); private static Map proxyClasses = Collections.synchronizedMap(new WeakHashMap()); protected InvocationHandler h; // 私有构造函数,不允许程序员通过构造函数来实例化Proxy,生成Proxy的实例,需要调用newProxyInstance方法 private Proxy() { } // 受保护的构造函数,这个函数也不允许程序员直接调用 protected Proxy(InvocationHandler h) { this.h = h; } public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException{ // 这行代码,可以说明,在Class类文件的数据结构中,接口interfaces占用2个字节,最大值65535 if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } Class proxyClass = null; String[] interfaceNames = new String[interfaces.length]; // Set是无序,不可重复的集合 Set interfaceSet = new HashSet(); for (int i = 0; i < interfaces.length; i++) { String interfaceName = interfaces[i].getName(); Class interfaceClass = null; try { // 通过接口名称和类加载器,获得接口实现类 interfaceClass = Class.forName(interfaceName, false, loader); } catch (ClassNotFoundException e) { } if (interfaceClass != interfaces[i]) { throw new IllegalArgumentException(interfaces[i] + " is not visible from class loader"); } if (!interfaceClass.isInterface()) { throw new IllegalArgumentException(interfaceClass.getName() + " is not an interface"); } if (interfaceSet.contains(interfaceClass)) { throw new IllegalArgumentException("repeated interface: " + interfaceClass.getName()); } interfaceSet.add(interfaceClass); interfaceNames[i] = interfaceName; } Object key = Arrays.asList(interfaceNames); Map cache; synchronized (loaderToCache) { cache = (Map) loaderToCache.get(loader); if (cache == null) { cache = new HashMap(); loaderToCache.put(loader, cache); } } synchronized (cache) { do { Object value = cache.get(key); if (value instanceof Reference) { proxyClass = (Class) ((Reference) value).get(); } if (proxyClass != null) { return proxyClass; } else if (value == pendingGenerationMarker) { try { cache.wait(); } catch (InterruptedException e) { } continue; } else { cache.put(key, pendingGenerationMarker); break; } } while (true); } try { String proxyPkg = null; 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) { proxyPkg = ""; } { long num; synchronized (nextUniqueNumberLock) { num = nextUniqueNumber++; } String proxyName = proxyPkg + proxyClassNamePrefix + num; byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces); try { proxyClass = defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); } catch (ClassFormatError e) { throw new IllegalArgumentException(e.toString()); } } proxyClasses.put(proxyClass, null); } finally { synchronized (cache) { if (proxyClass != null) { cache.put(key, new WeakReference(proxyClass)); } else { cache.remove(key); } cache.notifyAll(); } } return proxyClass; } public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException{ if (h == null) { throw new NullPointerException(); } // 获得代理类,需要传递2个参数,类加载器和接口 Class cl = getProxyClass(loader, interfaces); 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()); } } public static boolean isProxyClass(Class<?> cl) { if (cl == null) { throw new NullPointerException(); } return proxyClasses.containsKey(cl); } public static InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException{ 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); }
- package java.lang.reflect;
- import java.lang.ref.Reference;
- import java.lang.ref.WeakReference;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Map;
- import java.util.Set;
- import java.util.WeakHashMap;
- import sun.misc.ProxyGenerator;
- public class Proxy implements java.io.Serializable {
- private static final long serialVersionUID = -2222568056686623797L;
- private final static String proxyClassNamePrefix = "$Proxy";
- private final static Class[] constructorParams = { InvocationHandler.class };
- private static Map loaderToCache = new WeakHashMap();
- private static Object pendingGenerationMarker = new Object();
- private static long nextUniqueNumber = 0;
- private static Object nextUniqueNumberLock = new Object();
- private static Map proxyClasses = Collections.synchronizedMap(new WeakHashMap());
- protected InvocationHandler h;
- // 私有构造函数,不允许程序员通过构造函数来实例化Proxy,生成Proxy的实例,需要调用newProxyInstance方法
- private Proxy() {
- }
- // 受保护的构造函数,这个函数也不允许程序员直接调用
- protected Proxy(InvocationHandler h) {
- this.h = h;
- }
- public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException{
- // 这行代码,可以说明,在Class类文件的数据结构中,接口interfaces占用2个字节,最大值65535
- if (interfaces.length > 65535) {
- throw new IllegalArgumentException("interface limit exceeded");
- }
- Class proxyClass = null;
- String[] interfaceNames = new String[interfaces.length];
- // Set是无序,不可重复的集合
- Set interfaceSet = new HashSet();
- for (int i = 0; i < interfaces.length; i++) {
- String interfaceName = interfaces[i].getName();
- Class interfaceClass = null;
- try {
- // 通过接口名称和类加载器,获得接口实现类
- interfaceClass = Class.forName(interfaceName, false, loader);
- }
- catch (ClassNotFoundException e) {
- }
- if (interfaceClass != interfaces[i]) {
- throw new IllegalArgumentException(interfaces[i] + " is not visible from class loader");
- }
- if (!interfaceClass.isInterface()) {
- throw new IllegalArgumentException(interfaceClass.getName() + " is not an interface");
- }
- if (interfaceSet.contains(interfaceClass)) {
- throw new IllegalArgumentException("repeated interface: " + interfaceClass.getName());
- }
- interfaceSet.add(interfaceClass);
- interfaceNames[i] = interfaceName;
- }
- Object key = Arrays.asList(interfaceNames);
- Map cache;
- synchronized (loaderToCache) {
- cache = (Map) loaderToCache.get(loader);
- if (cache == null) {
- cache = new HashMap();
- loaderToCache.put(loader, cache);
- }
- }
- synchronized (cache) {
- do {
- Object value = cache.get(key);
- if (value instanceof Reference) {
- proxyClass = (Class) ((Reference) value).get();
- }
- if (proxyClass != null) {
- return proxyClass;
- }
- else if (value == pendingGenerationMarker) {
- try {
- cache.wait();
- }
- catch (InterruptedException e) {
- }
- continue;
- }
- else {
- cache.put(key, pendingGenerationMarker);
- break;
- }
- } while (true);
- }
- try {
- String proxyPkg = null;
- 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) {
- proxyPkg = "";
- }
- {
- long num;
- synchronized (nextUniqueNumberLock) {
- num = nextUniqueNumber++;
- }
- String proxyName = proxyPkg + proxyClassNamePrefix + num;
- byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces);
- try {
- proxyClass = defineClass0(loader, proxyName,
- proxyClassFile, 0, proxyClassFile.length);
- }
- catch (ClassFormatError e) {
- throw new IllegalArgumentException(e.toString());
- }
- }
- proxyClasses.put(proxyClass, null);
- }
- finally {
- synchronized (cache) {
- if (proxyClass != null) {
- cache.put(key, new WeakReference(proxyClass));
- }
- else {
- cache.remove(key);
- }
- cache.notifyAll();
- }
- }
- return proxyClass;
- }
- public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
- throws IllegalArgumentException{
- if (h == null) {
- throw new NullPointerException();
- }
- // 获得代理类,需要传递2个参数,类加载器和接口
- Class cl = getProxyClass(loader, interfaces);
- 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());
- }
- }
- public static boolean isProxyClass(Class<?> cl) {
- if (cl == null) {
- throw new NullPointerException();
- }
- return proxyClasses.containsKey(cl);
- }
- public static InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException{
- 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);
- }