标签:访问 expected min tar different assertion exist boolean help
上一章我们简单的讲解了什么是动态代理和如何使用动态代理。
//创建一个静态方法,生成代理类,public static Object newProxyInstance(Object speak){System.out.println(JDKDynamicProxy.class.getClassLoader().toString());return Proxy.newProxyInstance(JDKDynamicProxy.class.getClassLoader(),new Class[]{Speak.class,Eat.class}, new JDKDynamicProxy(speak));}
@CallerSensitivepublic static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException{if (h == null) {throw new NullPointerException();}final Class<?>[] intfs = interfaces.clone();//拷贝一份接口类数组,我们的例子是传入{Speak.class,Eat.class}final SecurityManager sm = System.getSecurityManager();//获取安全管理器组件if (sm != null) {//判断是否有权限去访问checkProxyAccess(Reflection.getCallerClass(), loader, intfs);}/** Look up or generate the designated proxy class.*///根据classloader和接口类数组动态创建Proxy.cassClass<?> cl = getProxyClass0(loader, intfs);/** Invoke its constructor with the designated invocation handler.*/try {//Proxy.class存在一个以InvocationHandler.class为类型的参数,获取该构造器//看起来是我们常用的代理模式final Constructor<?> cons = cl.getConstructor(constructorParams);final InvocationHandler ih = h;if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {//判断是Proxy.class是否包含不是public类型的接口// create proxy instance with doPrivilege as the proxy class may// implement non-public interfaces that requires a special permissionreturn AccessController.doPrivileged(new PrivilegedAction<Object>() {public Object run() {return newInstance(cons, ih);}});} else {//返回Proxy.class实例return newInstance(cons, ih);}} catch (NoSuchMethodException e) {throw new InternalError(e.toString());}}
private static Class<?> getProxyClass0(ClassLoader loader,Class<?>... interfaces) {if (interfaces.length > 65535) {//接口数量不能超过65535,刚好是一个int类型的最大值throw new IllegalArgumentException("interface limit exceeded");}// If the proxy class defined by the given loader implementing// the given interfaces exists, this will simply return the cached copy;// otherwise, it will create the proxy class via the ProxyClassFactoryreturn proxyClassCache.get(loader, interfaces);}
/*** a cache of proxy classes*/private static final WeakCache<ClassLoader, Class<?>[], Class<?>>proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

private final ReferenceQueue<K> refQueue = new ReferenceQueue();//弱引用队列//(ClassLoader key ,(<CLassloader,Class<?>[]> key ,Factory value) value)private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map = new ConcurrentHashMap();private final ConcurrentMap<Supplier<V>, Boolean> reverseMap = new ConcurrentHashMap();private final BiFunction<K, P, ?> subKeyFactory;//Key的创建工厂private final BiFunction<K, P, V> valueFactory;//value的创建工厂
//调用这个方法获取动态生成的classpublic V get(K paramK, P paramP){Objects.requireNonNull(paramP);//检测传入的接口数组是否为空expungeStaleEntries();//删除因为只有弱引用没有强引用指向的被gc回收后遗留下来的WeakReference对象,Object localObject1 = CacheKey.valueOf(paramK, this.refQueue); //创建一个CacheKey,paramK是ClassLoader对象,CacheKey是继承WeakReference类,Object localObject2 = (ConcurrentMap)this.map.get(localObject1);//判断map中是否存在相同的keyif (localObject2 == null)//不存在{localObject3 = (ConcurrentMap)this.map.putIfAbsent(localObject1, localObject2 = new ConcurrentHashMap());//不存在则存入<ClassLoader:localObject1,ConcurrentHashMap:localObject2>,若存在则map.get(localObject1)得到localObject3if (localObject3 != null)localObject2 = localObject3;}Object localObject3 = Objects.requireNonNull(this.subKeyFactory.apply(paramK, paramP));//创建二元键<classloader,Class<?>[]>Object localObject4 = (Supplier)((ConcurrentMap)localObject2).get(localObject3);//从localObject2根据我们给的<classloader,Class<?>[]>获取Value,有可能是Factory对象,也有可能是CacheValue对象,Factory则调用动态创建ProxyClass,创建完ProxyClass后封装成CacheValue,然后用CacheValue替换掉Factory。Factory localFactory = null;while (true){if (localObject4 != null){//核心代码Object localObject5 = ((Supplier)localObject4).get();//调用的有可能是Factory的get方法,也有可能是CacheValue的get方法if (localObject5 != null)return localObject5;}if (localFactory == null)//为该键值<classloader,intfaces>创建一个工厂localFactory = new Factory(paramK, paramP, localObject3, (ConcurrentMap)localObject2);if (localObject4 == null)//把创建的工厂放入localObject2中{localObject4 = (Supplier)((ConcurrentMap)localObject2).putIfAbsent(localObject3, localFactory);if (localObject4 != null)continue;localObject4 = localFactory;continue;}//当localObject4存在,但Facotry的get方法并返回null时,就替换掉replace(K key, V oldValue, V newValue)if (((ConcurrentMap)localObject2).replace(localObject3, localObject4, localFactory)){localObject4 = localFactory;continue;}localObject4 = (Supplier)((ConcurrentMap)localObject2).get(localObject3);}}
public synchronized V get(){//factory获取WeakCache.Supplier localSupplier = (WeakCache.Supplier)this.valuesMap.get(this.subKey);if (localSupplier != this)return null;Object localObject1 = null;try{//调用ProxyClassFactory的apply,返回Class类型为localObject1localObject1 = Objects.requireNonNull(WeakCache.this.valueFactory.apply(this.key, this.parameter));}finally{if (localObject1 == null)this.valuesMap.remove(this.subKey, this);}assert (localObject1 != null);WeakCache.CacheValue localCacheValue = new WeakCache.CacheValue(localObject1);//因为Factory和CacheValue都继承Supplier,故可以将原本指向Factory对象替换成指向CacheValueif (this.valuesMap.replace(this.subKey, this, localCacheValue))//缓存ClassWeakCache.this.reverseMap.put(localCacheValue, Boolean.TRUE);elsethrow new AssertionError("Should not reach here");return localObject1;}
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
/*** A factory function that generates, defines and returns the proxy class given* the ClassLoader and array of interfaces.*/private static final class ProxyClassFactoryimplements BiFunction<ClassLoader, Class<?>[], Class<?>>{// prefix for all proxy class names//定义类名前缀private static final String proxyClassNamePrefix = "$Proxy";// next number to use for generation of unique proxy class names//生成类序列号和$Proxy组合成类名private static final AtomicLong nextUniqueNumber = new AtomicLong();@Overridepublic 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) {}if (interfaceClass != intf) {throw new IllegalArgumentException(intf + " 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");}/** Verify that this interface is not a duplicate.*///判断是否有重复的接口if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {throw new IllegalArgumentException("repeated interface: " + interfaceClass.getName());}}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.*/
//判断是否存在接口类不是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) {// if no non-public proxy interfaces, use com.sun.proxy packageproxyPkg = ReflectUtil.PROXY_PACKAGE + ".";}/** Choose a name for the proxy class to generate.*///获取这次动态代理生成class的序列号long num = nextUniqueNumber.getAndIncrement();String proxyName = proxyPkg + proxyClassNamePrefix + num;/** Generate the specified proxy class.*///主要代码,生成ProxyClass的java字节码文件
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces);try {//defineClass函数会校验class文件并将class文件加载并返回成Class对象return 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());}}}
byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces);
public static byte[] generateProxyClass(String paramString, Class[] paramArrayOfClass){ProxyGenerator localProxyGenerator = new ProxyGenerator(paramString, paramArrayOfClass);//核心代码
byte[] arrayOfByte = localProxyGenerator.generateClassFile();//是否保存生成的class文件到本地文件系统,其中saveGeneratedFiles是由saveGeneratedFiles = ((Boolean)AccessController.doPrivileged(new GetBooleanAction("sun.misc.ProxyGenerator.saveGeneratedFiles"))).booleanValue();//控制,若想看到生成的class,只需要在测试代码中将系统配置属性Sytem.properties里的sun.misc.ProxyGenerator.saveGeneratedFiles改为true就行了,还有就是在项目下建立:com.sun.proxy,否则报fileNotFoundif (saveGeneratedFiles)AccessController.doPrivileged(new PrivilegedAction(paramString, arrayOfByte){public Void run(){try{FileOutputStream localFileOutputStream = new FileOutputStream(ProxyGenerator.access$000(this.val$name) + ".class");localFileOutputStream.write(this.val$classFile);localFileOutputStream.close();return null;}catch (IOException localIOException){}throw new InternalError("I/O exception saving generated file: " + localIOException);}});return arrayOfByte;}
//是否保存生成的class文件到本地文件系统,其中saveGeneratedFiles是由saveGeneratedFiles = ((Boolean)AccessController.doPrivileged(new GetBooleanAction("sun.misc.ProxyGenerator.saveGeneratedFiles"))).booleanValue();//控制,若想看到生成的class,只需要在测试代码中将系统配置属性Sytem.properties里的sun.misc.ProxyGenerator.saveGeneratedFiles改为true就行了,还有就是在项目下建立:com.sun.proxy,否则报fileNotFound
public static void writeToDisk(String path) {byte[] class = ProxyGenerator.generateProxyClass("$Proxy0", Star.class.getInterfaces());FileOutputStream out = null;try {out = new FileOutputStream(path);out.write(class);out.flush();} catch (Exception e) {e.printStackTrace();} finally {try {out.close();} catch (IOException e) {e.printStackTrace();}}}
private byte[] generateClassFile(){//添加hashCode函数字节码addProxyMethod(hashCodeMethod, Object.class);//添加equals函数字节码addProxyMethod(equalsMethod, Object.class);//添加toString函数字节码addProxyMethod(toStringMethod, Object.class);//循环添加接口的方法字节码,存储到名为ProxyMethods的Map中,其Key(String)是方法的字符串如//java/io/PrintStream.println:(Ljava/lang/String;),value是List<ProxyMethod>,for (int i = 0; i < this.interfaces.length; i++){localObject1 = this.interfaces[i].getMethods();for (int k = 0; k < localObject1.length; k++)addProxyMethod(localObject1[k], this.interfaces[i]);}Iterator localIterator1 = this.proxyMethods.values().iterator();while (localIterator1.hasNext()){localObject1 = (List)localIterator1.next();//校验List<ProxyMethod>(有可能有函数名相同的函数,来自不同的接口,但返回类不一样),判断这些返回类中是否有共同的父类,并设置为函数最终返回类型checkReturnTypes((List)localObject1);}Object localObject2;try{//methods存储的是最终要输出到Class的函数this.methods.add(generateConstructor());//添加构造器localIterator1 = this.proxyMethods.values().iterator();while (localIterator1.hasNext()){localObject1 = (List)localIterator1.next();Iterator localIterator2 = ((List)localObject1).iterator();while (localIterator2.hasNext()){localObject2 = (ProxyMethod)localIterator2.next();//ProxyClass的成员,成员的类型都是反射Method类型this.fields.add(new FieldInfo(((ProxyMethod)localObject2).methodFieldName, "Ljava/lang/reflect/Method;", 10));//添加方法- this.methods.add(((ProxyMethod)localObject2).generateMethod());
}}//添加静态的初始化模块:static{}this.methods.add(generateStaticInitializer());}catch (IOException localIOException1){throw new InternalError("unexpected I/O Exception");}if (this.methods.size() > 65535)//throw new IllegalArgumentException("method limit exceeded");if (this.fields.size() > 65535)throw new IllegalArgumentException("field limit exceeded");//下面是常量池的创建赋值this.cp.getClass(dotToSlash(this.className));this.cp.getClass("java/lang/reflect/Proxy");for (int j = 0; j < this.interfaces.length; j++)this.cp.getClass(dotToSlash(this.interfaces[j].getName()));this.cp.setReadOnly();//最终输出Class文件,如果有兴趣可以去看一下java的字节码结构和含义ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();Object localObject1 = new DataOutputStream(localByteArrayOutputStream);try{((DataOutputStream)localObject1).writeInt(-889275714);((DataOutputStream)localObject1).writeShort(0);((DataOutputStream)localObject1).writeShort(49);this.cp.write((OutputStream)localObject1);((DataOutputStream)localObject1).writeShort(49);((DataOutputStream)localObject1).writeShort(this.cp.getClass(dotToSlash(this.className)));((DataOutputStream)localObject1).writeShort(this.cp.getClass("java/lang/reflect/Proxy"));((DataOutputStream)localObject1).writeShort(this.interfaces.length);for (int m = 0; m < this.interfaces.length; m++)((DataOutputStream)localObject1).writeShort(this.cp.getClass(dotToSlash(this.interfaces[m].getName())));((DataOutputStream)localObject1).writeShort(this.fields.size());Iterator localIterator3 = this.fields.iterator();while (localIterator3.hasNext()){localObject2 = (FieldInfo)localIterator3.next();((FieldInfo)localObject2).write((DataOutputStream)localObject1);}((DataOutputStream)localObject1).writeShort(this.methods.size());localIterator3 = this.methods.iterator();while (localIterator3.hasNext()){localObject2 = (MethodInfo)localIterator3.next();((MethodInfo)localObject2).write((DataOutputStream)localObject1);}((DataOutputStream)localObject1).writeShort(0);}catch (IOException localIOException2){throw new InternalError("unexpected I/O Exception");}return (B)(B)localByteArrayOutputStream.toByteArray();}
import cglib.Eat;import cglib.Speak;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.UndeclaredThrowableException;public final class $Proxy0 extends Proxyimplements Speak, Eat{//对应this.fields.add(new FieldInfo(((ProxyMethod)localObject2).methodFieldName, "Ljava/lang/reflect/Method;", 10));private static Method m3;private static Method m1;private static Method m4;private static Method m0;private static Method m2;// 对应this.methods.add(generateConstructor());//添加构造器public $Proxy0(InvocationHandler paramInvocationHandler)throws{super(paramInvocationHandler);}//对应this.methods.add(((ProxyMethod)localObject2).generateMethod());public final void say()throws{try{this.h.invoke(this, m3, null);return;}catch (RuntimeException localRuntimeException){throw localRuntimeException;}catch (Throwable localThrowable){}throw new UndeclaredThrowableException(localThrowable);}public final boolean equals(Object paramObject)throws{try{return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();}catch (RuntimeException localRuntimeException){throw localRuntimeException;}catch (Throwable localThrowable){}throw new UndeclaredThrowableException(localThrowable);}public final void eat()throws{try{this.h.invoke(this, m4, null);return;}catch (RuntimeException localRuntimeException){throw localRuntimeException;}catch (Throwable localThrowable){}throw new UndeclaredThrowableException(localThrowable);}public final int hashCode()throws{try{return ((Integer)this.h.invoke(this, m0, null)).intValue();}catch (RuntimeException localRuntimeException){throw localRuntimeException;}catch (Throwable localThrowable){}throw new UndeclaredThrowableException(localThrowable);}public final String toString()throws{try{return (String)this.h.invoke(this, m2, null);}catch (RuntimeException localRuntimeException){throw localRuntimeException;}catch (Throwable localThrowable){}throw new UndeclaredThrowableException(localThrowable);}//对应this.methods.add(generateStaticInitializer());static{try{m3 = Class.forName("cglib.Speak").getMethod("say", new Class[0]);m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });m4 = Class.forName("cglib.Eat").getMethod("eat", new Class[0]);m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);return;}catch (NoSuchMethodException localNoSuchMethodException){throw new NoSuchMethodError(localNoSuchMethodException.getMessage());}catch (ClassNotFoundException localClassNotFoundException){}throw new NoClassDefFoundError(localClassNotFoundException.getMessage());}}
标签:访问 expected min tar different assertion exist boolean help
原文地址:http://www.cnblogs.com/zhenyimo/p/6837326.html