JDK7动态代理源码分析
IObject proxy = (IObject) Proxy.newProxyInstance(IObject.class.getClassLoader(),
new Class[]{IObject.class}, new DynamicProxyHandler(real) );
使用Proxy类的静态方法newProxyInstance创建一个动态代理类
查看API文档:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException loader - 定义代理类的类加载器 interfaces - 代理类要实现的接口列表 h - 指派方法调用的调用处理程序
1、JDK动态代理要求,被代理的必须是个接口,单纯的类则不行,即interfaces必须是接口
2、JDK代理所生成的代理类都会继承Proxy类,同时代理类会实现所有传入的接口列表(即interfaces),因此可以强制类型转换成接口类型。
3、如果非要代理一个没有实现接口的类,同时该类的方法与其他接口的方法相同,则需要利用反射实现
//利用反射获取你想代理的类的方法 Method myMethod = targetClass.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes()); myMethod.setAccessible(true);
4、newProxyInstance方法相当于getProxyClass方法
Proxy.getProxyClass(loader, interfaces). getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler });
源码分析:
@CallerSensitive public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { if (h == null) { throw new NullPointerException(); } //拷贝一份所有接口的数组 final Class<?>[] intfs = interfaces.clone(); /** * 安全管理器主要用来防止恶意攻击,根据java安全策略文件觉得将哪组权限授予类 * 每个java应用都有自己的安全管理器, * 如果要使用,可以在jvm启动时设定-Djava.security.manager选项,还可以同时指定安全策略文件。 * 如果在应用中启用了Java安全管理器,却没有指定安全策略文件,那么Java安全管理器将使用默认的安全策略,它们是由位于目录$JAVA_HOME/jre /lib/security中的java.policy定义的。 */ final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } /** * 调用getProxyClass0方法拿到代理类的Class对象 */ Class<?> cl = getProxyClass0(loader, intfs);
调用getProxyClass0:
/** 代理类的缓存 */
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { //如果目标类的接口数大于65535 if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } // 如果代理类已经在缓存中,则直接取出,否则用ProxyClassFactory创建新代理类 return proxyClassCache.get(loader, interfaces); }
调用WeakCache的get方法:
private final ReferenceQueue<K> refQueue
= new ReferenceQueue<>();
/** * K 表示key * P 表示parameters * V 表示value */ public V get(K key, P parameter) { //NullObject判断方法 Objects.requireNonNull(parameter); //清理持有弱引用的WeakHashMap这种数据结构 expungeStaleEntries(); //从队列中获取cacheKey Object cacheKey = CacheKey.valueOf(key, refQueue);
调用CacheKey的valueOf
java.lang.ref.Reference
Reference(T referent, ReferenceQueue<? super T> queue) {
this.referent = referent;
this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
}
private static final class CacheKey<K> extends WeakReference<K> { // a replacement for null keys private static final Object NULL_KEY = new Object(); static <K> Object valueOf(K key, ReferenceQueue<K> refQueue) { return key == null ? NULL_KEY : new CacheKey<>(key, refQueue); } private final int hash; private CacheKey(K key, ReferenceQueue<K> refQueue) { super(key, refQueue);
//返回给定对象的哈希码,
//该代码与默认的方法 hashCode() 返回的代码一样,无论给定对象的类是否重写 hashCode()。null 引用的哈希码为 0。 this.hash = System.identityHashCode(key); }
ReferenceQueue的源码先暂时不分析,回到WeakCache中get方法
//利用懒加载的方式获取cacheKey对应的Supplier ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); //如果map中不存在cache键值对,则把cacheKey对应的键值对放进map if (valuesMap == null) { ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>()); if (oldValuesMap != null) { valuesMap = oldValuesMap; } } // create subKey and retrieve the possible Supplier<V> stored by that // subKeyFactory.apply调用Proxy中KeyFactory静态类的apply方法 Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
subKeyFactory.apply调用Proxy中KeyFactory静态类的apply方法
private static final class KeyFactory implements BiFunction<ClassLoader, Class<?>[], Object> { @Override public Object apply(ClassLoader classLoader, Class<?>[] interfaces) { switch (interfaces.length) { case 1: return new Key1(interfaces[0]); // the most frequent case 2: return new Key2(interfaces[0], interfaces[1]); case 0: return key0; default: return new KeyX(interfaces); } } }
Key1、Key2、KeyX都是Proxy的内部类
/* * Key1 and Key2 都是用来给实现了1个或者2个接口的代理类使用 */ private static final class Key1 extends WeakReference<Class<?>> { private final int hash; Key1(Class<?> intf) { super(intf); this.hash = intf.hashCode(); } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { Class<?> intf; return this == obj || obj != null && obj.getClass() == Key1.class && (intf = get()) != null && intf == ((Key1) obj).get(); } } private static final class Key2 extends WeakReference<Class<?>> { private final int hash; private final WeakReference<Class<?>> ref2; Key2(Class<?> intf1, Class<?> intf2) { super(intf1); hash = 31 * intf1.hashCode() + intf2.hashCode(); ref2 = new WeakReference<Class<?>>(intf2); } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { Class<?> intf1, intf2; return this == obj || obj != null && obj.getClass() == Key2.class && (intf1 = get()) != null && intf1 == ((Key2) obj).get() && (intf2 = ref2.get()) != null && intf2 == ((Key2) obj).ref2.get(); } } /* * 用来给实现了3个或3个以上接口的代理类使用 */ private static final class KeyX { private final int hash; private final WeakReference<Class<?>>[] refs; KeyX(Class<?>[] interfaces) { hash = Arrays.hashCode(interfaces); refs = new WeakReference[interfaces.length]; for (int i = 0; i < interfaces.length; i++) { refs[i] = new WeakReference(interfaces[i]); } } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { return this == obj || obj != null && obj.getClass() == KeyX.class && equals(refs, ((KeyX) obj).refs); } private static boolean equals(WeakReference<Class<?>>[] refs1, WeakReference<Class<?>>[] refs2) { if (refs1.length != refs2.length) { return false; } for (int i = 0; i < refs1.length; i++) { Class<?> intf = refs1[i].get(); if (intf == null || intf != refs2[i].get()) { return false; } } return true; } }
回到get方法:
// Supplier<V> supplier = valuesMap.get(subKey); Factory factory = null; while (true) { if (supplier != null) { //调用Factory实现的get方法,返回实现InvokeHandler的类,并包含了所需要的信息 V value = supplier.get(); if (value != null) { return value; } } //懒加载构建工厂 if (factory == null) { /** *创建一个工厂 key classloader parameter interfaces接口 subkey 存储interfaces的对象 valuesMap cacheKey键值对 */ factory = new Factory(key, parameter, subKey, valuesMap); } if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { //填充supplier supplier = factory; } } else { if (valuesMap.replace(subKey, supplier, factory)) { supplier = factory; } else { supplier = valuesMap.get(subKey); } } }
调用Supplier子类Factory的get方法:
@Override public synchronized V get() { // 重新检查supplier Supplier<V> supplier = valuesMap.get(subKey); if (supplier != this) { return null; } V value = null; try { //调用Proxy类种ProxyFactoryClass的apply方法,apply才是真正创建代理类的方法 value = Objects.requireNonNull(valueFactory.apply(key, parameter)); } finally { if (value == null) { // remove us on failure valuesMap.remove(subKey, this); } } // the only path to reach here is with non-null value assert value != null; // wrap value with CacheValue (WeakReference) CacheValue<V> cacheValue = new CacheValue<>(value); // try replacing us with CacheValue (this should always succeed) if (valuesMap.replace(subKey, this, cacheValue)) { // put also in reverseMap reverseMap.put(cacheValue, Boolean.TRUE); } else { throw new AssertionError("Should not reach here"); } // successfully replaced us with new CacheValue -> return the value // wrapped by it return value; }
调用ProxyFactoryClass的apply方法:
private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> { //动态代理类的前缀 private static final String proxyClassNamePrefix = "$Proxy"; //最终动态代理类的名字一般都是$ProxyN (N=0,1,2,3,4,5,6,7,8) private static final AtomicLong nextUniqueNumber = new AtomicLong(); //真正创建代理类的方法 @Override public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) { Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length); for (Class<?> intf : interfaces) { /* * Verify that the class loader resolves the name of this * interface to the same Class object. */ Class<?> interfaceClass = null; try { //加载每一个接口运行时的信息,返回接口对应的类对象 interfaceClass = Class.forName(intf.getName(), false, loader); } catch (ClassNotFoundException e) { } //如果使你自己定义的ClassLoader加载的class与你传入的class不一样,则抛出异常 if (interfaceClass != intf) { throw new IllegalArgumentException( intf + " is not visible from class loader"); } /* * 判断Class对象是否是一个接口 */ if (!interfaceClass.isInterface()) { throw new IllegalArgumentException( interfaceClass.getName() + " is not an interface"); } /* * 验证接口是否重复 */ if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) { throw new IllegalArgumentException( "repeated interface: " + interfaceClass.getName()); } } String proxyPkg = null; // package to define proxy class in /* * 检查传入的接口里有没有不是public的接口,如果有,这些接口必须在一个包里 */ for (Class<?> intf : interfaces) { int flags = intf.getModifiers(); if (!Modifier.isPublic(flags)) { String name = intf.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) { //如果没有非公共的代理接口, 则使用com.sun.proxy package proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; } //为生成的代理类选择一个名字 com.sun.proxy $Proxy0 long num = nextUniqueNumber.getAndIncrement(); String proxyName = proxyPkg + proxyClassNamePrefix + num; //生成代理类字节码 byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces); try { //根据代理类的字节码生成代理类的实例 return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); } catch (ClassFormatError e) { throw new IllegalArgumentException(e.toString()); } } }
调用ProxyGenerator.generateProxyClass( proxyName, interfaces);生成接口对应的字节码
public static byte[] generateProxyClass(final String name, Class[] interfaces) { ProxyGenerator gen = new ProxyGenerator(name, interfaces);
//生成字节码 final byte[] classFile = gen.generateClassFile(); if (saveGeneratedFiles) { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { try { FileOutputStream file = new FileOutputStream(dotToSlash(name) + ".class"); file.write(classFile); file.close(); return null; } catch (IOException e) { throw new InternalError( "I/O exception saving generated file: " + e); } } }); } return classFile; }
调用Proxy.defineClass0本地方法把字节码生成代理类的实例