代理模式

247 阅读8分钟

1:相关网页

2:零散的点

  1. 静态代理简单实现 :个人客户通过房产中介买房
public interface BuyHouse{
    public void buyHouse();
}
public class Customer implements BuyHouse{
    @Override
    public void buyHouse(){
        L.d("Customer buyHouse");
    }
}
public class Agent implements BuyHouse{
    private BuyHouse realBuyer;
    public Agent(){
        realBuyer = new Customer();
    }
    @Override
    public void buyHouse(){
        L.d("Agent buyHouse 开始");
        if(realBuyer != null){
            realBuyer.buyHouse();
        }
        L.d("Agent buyHouse 结束");
    }
}

BuyHouse agent = new Agent();
agent.buyHouse();

3:动态代理

  1. 动态代理简单实现
public interface Buyer {
    public void buy();
}
public class Buyer1 implements Buyer {
    @Override
    public void buy() {
        L.d("Buyer","Buyer1 buy:买苹果");
    }
}
public class Buyer2 implements Buyer {
    @Override
    public void buy() {
        L.d("Buyer","Buyer2 buy:买香蕉");
    }
}
public class DynamicProxy implements InvocationHandler {
    private Object realObject;
    public Object newProxyInstance(Object realObject){
        this.realObject = realObject;
        return Proxy.newProxyInstance(realObject.getClass().getClassLoader(),realObject.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(this.realObject != null){
            return method.invoke(realObject,args);
        }
        return null;
    }
}

调用:
public void func1(View view) {
    DynamicProxy proxy = new DynamicProxy();
    Buyer buyer1 = new Buyer1();
    Buyer buyer1_proxy = (Buyer) proxy.newProxyInstance(buyer1);
    buyer1_proxy.buy();
    Buyer buyer2 = new Buyer2();
    Buyer buyer2_proxy = (Buyer) proxy.newProxyInstance(buyer2);
    buyer2_proxy.buy();
}
log打印:
2020-08-03 17:22:42.809 2488-2488/? D/Buyer: Buyer1 buy:买苹果
2020-08-03 17:22:42.809 2488-2488/? D/Buyer: Buyer2 buy:买香蕉
  1. 动态代理生成的类结构
    public interface Operate {
        public void operateMethod1();
        public void operateMethod2();
        public void operateMethod3();
    }
    
    public class OperateImpl implements Operate {
        @Override
        public void operateMethod1() {
            System.out.println("Invoke operateMethod1");
            sleep(110);
        }
        @Override
        public void operateMethod2() {
            System.out.println("Invoke operateMethod2");
            sleep(120);
        }
        @Override
        public void operateMethod3() {
            System.out.println("Invoke operateMethod3");
            sleep(130);
        }
        private static void sleep(long millSeconds) {
            try {
                Thread.sleep(millSeconds);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public class TimingInvocationHandler implements InvocationHandler {
        private Object target;
        public TimingInvocationHandler() {}
        public TimingInvocationHandler(Object target) {
            this.target = target;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            long start = System.currentTimeMillis();
            Object obj = method.invoke(target, args);
            System.out.println(method.getName() + " cost time is:" + (System.currentTimeMillis() - start));
            return obj;
        }
    }
    
    public class ProxyUtils {
        /**
         * Save proxy class to path
         *
         * @param path path to save proxy class
         * @param proxyClassName name of proxy class
         * @param interfaces interfaces of proxy class
         * @return
         */
        public static boolean saveProxyClass(String path, String proxyClassName, Class[] interfaces) {
            if (proxyClassName == null || path == null) {
                return false;
            }
            // get byte of proxy class
            // 关键:通过 ProxyGenerator
            byte[] classFile = ProxyGenerator.generateProxyClass(proxyClassName, interfaces);
            FileOutputStream out = null;
            try {
                out = new FileOutputStream(path);
                out.write(classFile);
                out.flush();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return false;
        }
    }
    
    调用,查看生成的动态代理类实际结构
    public class T {
        public static void main(String[] args) {
            TimingInvocationHandler timingInvocationHandler = new TimingInvocationHandler(new OperateImpl());
            Operate operate = (Operate)(Proxy.newProxyInstance(Operate.class.getClassLoader(), new Class[] {Operate.class},
                    timingInvocationHandler));
    
            // call proxy instance method
            operate.operateMethod1();
            System.out.println();
            operate.operateMethod2();
            System.out.println();
            operate.operateMethod3();
    
            // print info of proxy class
            System.out.println("proxy class is: " + operate.getClass().getName());
            System.out.println("\r\nsuper class of proxy class is: " + operate.getClass().getSuperclass().getName());
            System.out.println("\r\ninterfaces of proxy class are: ");
            for (Class inter : operate.getClass().getInterfaces()) {
                System.out.println("\t" + inter.getName());
            }
            System.out.println("\r\nmethods of proxy class are: ");
            for (Method method : operate.getClass().getMethods()) {
                System.out.println("\t" + method.getName());
            }
    
            // save proxy class to root of this project, you can use jd-gui to see content of the saved file
            //String saveFileName = "$Proxy0.class";
            String saveFileName = "$Proxy0.txt";
            ProxyUtils.saveProxyClass(saveFileName, operate.getClass().getSimpleName(), operate.getClass().getInterfaces());
            System.out.println("\r\nContent of " + operate.getClass().getSimpleName() + ".class has saved to file "
                    + saveFileName + " at root of this project");
        }
    }
    
    Invoke operateMethod1
    operateMethod1 cost time is:111
    
    Invoke operateMethod2
    operateMethod2 cost time is:120
    
    Invoke operateMethod3
    operateMethod3 cost time is:130
    proxy class is: com.sun.proxy.$Proxy0
    
    super class of proxy class is: java.lang.reflect.Proxy
    
    interfaces of proxy class are: 
        com.huanhailiuxin.project2020.proxy.Operate
    
    methods of proxy class are: 
        operateMethod1
        operateMethod2
        operateMethod3
        equals
        toString
        hashCode
        getInvocationHandler
        getProxyClass
        newProxyInstance
        isProxyClass
        wait
        wait
        wait
        getClass
        notify
        notifyAll
    
    Content of $Proxy0.class has saved to file $Proxy0.class at root of this project
    
    package defpackage;
    
    import com.huanhailiuxin.project2020.proxy.Operate;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.lang.reflect.UndeclaredThrowableException;
    
    /* renamed from: $Proxy0 reason: invalid class name and default package */
    public final class C$Proxy0 extends Proxy implements Operate {
        private static Method m0;
        private static Method m1;
        private static Method m2;
        private static Method m3;
        private static Method m4;
        private static Method m5;
    
        static {
            try {
                m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
                m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
                m4 = Class.forName("com.huanhailiuxin.project2020.proxy.Operate").getMethod("operateMethod2", new Class[0]);
                m5 = Class.forName("com.huanhailiuxin.project2020.proxy.Operate").getMethod("operateMethod3", new Class[0]);
                m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
                m3 = Class.forName("com.huanhailiuxin.project2020.proxy.Operate").getMethod("operateMethod1", new Class[0]);
            } catch (NoSuchMethodException e) {
                throw new NoSuchMethodError(e.getMessage());
            } catch (ClassNotFoundException e2) {
                throw new NoClassDefFoundError(e2.getMessage());
            }
        }
    
        public C$Proxy0(InvocationHandler invocationHandler) {
            super(invocationHandler);
        }
    
        public final boolean equals(Object obj) {
            try {
                return ((Boolean) this.h.invoke(this, m1, new Object[]{obj})).booleanValue();
            } catch (Error | RuntimeException e) {
                throw e;
            } catch (Throwable th) {
                throw new UndeclaredThrowableException(th);
            }
        }
    
        public final int hashCode() {
            try {
                return ((Integer) this.h.invoke(this, m0, null)).intValue();
            } catch (Error | RuntimeException e) {
                throw e;
            } catch (Throwable th) {
                throw new UndeclaredThrowableException(th);
            }
        }
    
        public final void operateMethod1() {
            try {
                this.h.invoke(this, m3, null);
            } catch (Error | RuntimeException e) {
                throw e;
            } catch (Throwable th) {
                throw new UndeclaredThrowableException(th);
            }
        }
    
        public final void operateMethod2() {
            try {
                this.h.invoke(this, m4, null);
            } catch (Error | RuntimeException e) {
                throw e;
            } catch (Throwable th) {
                throw new UndeclaredThrowableException(th);
            }
        }
    
        public final void operateMethod3() {
            try {
                this.h.invoke(this, m5, null);
            } catch (Error | RuntimeException e) {
                throw e;
            } catch (Throwable th) {
                throw new UndeclaredThrowableException(th);
            }
        }
    
        public final String toString() {
            try {
                return (String) this.h.invoke(this, m2, null);
            } catch (Error | RuntimeException e) {
                throw e;
            } catch (Throwable th) {
                throw new UndeclaredThrowableException(th);
            }
        }
    }
    
  2. Proxy.newProxyInstance
//仅保留关键代码
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
    throws IllegalArgumentException
{
	//1:查询或生成 动态代理类 的Class
    //关注点1
    Class<?> cl = getProxyClass0(loader, interfaces);

    //2:获取 动态代理类 的构造函数
    final Constructor<?> cons = cl.getConstructor(constructorParams);
    final InvocationHandler ih = h;
    //2:通过构造函数,以传入参数 h 构造Object数组作为参数,创建 动态代理类实例
    return cons.newInstance(new Object[]{h});
}
可见,重点在于如何获取动态代理类的Class.

-->

关注点1:
Class<?> cl = getProxyClass0(loader, interfaces);
private static Class<?> getProxyClass0(ClassLoader loader,
                                       Class<?>... interfaces) {
    if (interfaces.length > 65535) {
        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 ProxyClassFactory
    // 如果 指定的(类加载器 + 接口class数组) 对应的 动态代理类Class 已存在,则直接返回;
    // 若不存在,则通过 ProxyClassFactory 生成Class后返回.
    return proxyClassCache.get(loader, interfaces);
}
刚刚获取,肯定是不存在的,直接看 通过 ProxyClassFactory 生成Class 的逻辑.
-->
proxyClassCache:
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
-->
new ProxyClassFactory():
-->
ProxyClassFactory:
private static final class ProxyClassFactory
    implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
    // 所有动态代理类名称前缀都是 "$Proxy"
    private static final String proxyClassNamePrefix = "$Proxy";

    // next number to use for generation of unique proxy class names
    private static final AtomicLong nextUniqueNumber = new AtomicLong();

	//生成动态代理类Class的方法
    @Override
    public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
        Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
        ***
		//动态代理类的包名
        String proxyPkg = null;     // package to define proxy class in
        int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

        // 获取非public接口所在包,生成的动态代理类会和非public接口在同一个包内.
        // proxyPkg
        // 需要所有的非public接口都处于同一个包内.否则会抛出异常.
        for (Class<?> intf : interfaces) {
            int flags = intf.getModifiers();
            if (!Modifier.isPublic(flags)) {
                accessFlags = Modifier.FINAL;
                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)) {
                	//非public接口处于不同包,则抛出异常
                    throw new IllegalArgumentException(
                        "non-public interfaces from different packages");
                }
            }
        }

        if (proxyPkg == null) {
            // 如果没有非public接口,则 保持为null,为其赋默认值 "com.sun.proxy."
            proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
        }

        //动态代理类名称数字后缀
        //private static final AtomicLong nextUniqueNumber = new AtomicLong();
        //说明多次调用 Proxy.newProxyInstance ,生成的动态代理类名称后缀依次是 0,1,2,**
        long num = nextUniqueNumber.getAndIncrement();
        //动态代理类名称: 包名 + "$Proxy" + 数字(0,1,2 依次累加)
        String proxyName = proxyPkg + proxyClassNamePrefix + num;

        //获取动态代理类的byte数组
        //关注点2
        byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
        //根据动态代理类的byte数组,获取对应的Class实例返回
        return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
    }
}
可见,重点在于 ProxyGenerator.generateProxyClass 的实现逻辑.如果获取动态代理类的byte数组.

-->

关注点2:
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
-->
ProxyGenerator可以通过Android Studio看源码.
ProxyGenerator:
public class ProxyGenerator {
	//构造函数
    //动态代理类类名, 动态代理类需要实现的所有接口Class数组
    private ProxyGenerator(String var1, Class<?>[] var2, int var3) {
        this.className = var1;
        this.interfaces = var2;
        this.accessFlags = var3;
    }
    public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
    	//创建 ProxyGenerator 实例
        ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
        //调用其 generateClassFile 方法, 获取byte[]
        //关注点3
        final byte[] var4 = var3.generateClassFile();
        ***
		//返回 byte[]
        return var4;
    }
}
-->
关注点3:
private Map<String, List<ProxyGenerator.ProxyMethod>> proxyMethods = new HashMap();
//3.1
//addProxyMethod
private void addProxyMethod(Method var1, Class<?> var2) {
	//获取方法各个属性
    String var3 = var1.getName();
    Class[] var4 = var1.getParameterTypes();
    Class var5 = var1.getReturnType();
    Class[] var6 = var1.getExceptionTypes();
    String var7 = var3 + getParameterDescriptors(var4);
    //根据方法关联属性,获取对应的 List<ProxyGenerator.ProxyMethod>实例 var8 是否存在
    Object var8 = (List)this.proxyMethods.get(var7);
    if (var8 != null) {
    	//var8存在则说明对应的方法之前添加过,直接return
        ***
        reuturn
    } else {
    	//var8不存在,则创建对应ArrayList
        //并将 var8 存储到 proxyMethods 映射中
        var8 = new ArrayList(3);
        this.proxyMethods.put(var7, var8);
    }
	//创建新的new ProxyGenerator.ProxyMethod实例,添加到 var8 中
    //new ProxyGenerator.ProxyMethod(var3, var4, var5, var6, var2)
    ((List)var8).add(new ProxyGenerator.ProxyMethod(var3, var4, var5, var6, var2));
}

//3.2
private List<ProxyGenerator.MethodInfo> methods = new ArrayList();
//3.3
private List<ProxyGenerator.FieldInfo> fields = new ArrayList();
//可见: methods存储了所有方法, fields存储了所有成员变量/属性.

private byte[] generateClassFile() {
	//看addProxyMethod
    //3.1
    this.addProxyMethod(hashCodeMethod, Object.class);
    this.addProxyMethod(equalsMethod, Object.class);
    this.addProxyMethod(toStringMethod, Object.class);
    Class[] var1 = this.interfaces;
    int var2 = var1.length;

    int var3;
    Class var4;
    for(var3 = 0; var3 < var2; ++var3) {
        var4 = var1[var3];
        Method[] var5 = var4.getMethods();
        int var6 = var5.length;

        for(int var7 = 0; var7 < var6; ++var7) {
            Method var8 = var5[var7];
            //将所有接口中的方法都存储到 proxyMethods 中.
            this.addProxyMethod(var8, var4);
        }
    }
	//上面已经将所有接口中的方法存储到 proxyMethods 中
    //现在遍历 proxyMethods .
    Iterator var11 = this.proxyMethods.values().iterator();

    List var12;
    while(var11.hasNext()) {
        var12 = (List)var11.next();
        checkReturnTypes(var12);
    }

    Iterator var15;
    try {
    	//3.2
        //this.methods
        //向methods中添加构造方法信息
        //3.2.1
        //构造方法
        this.methods.add(this.generateConstructor());
        var11 = this.proxyMethods.values().iterator();

        while(var11.hasNext()) {
            var12 = (List)var11.next();
            var15 = var12.iterator();

            while(var15.hasNext()) {
                ProxyGenerator.ProxyMethod var16 = (ProxyGenerator.ProxyMethod)var15.next();
                //3.3
                //this.fields
                //向fields中添加成员变量信息.每一个原始的接口方法,都对应1个成员变量
                this.fields.add(new ProxyGenerator.FieldInfo(var16.methodFieldName, "Ljava/lang/reflect/Method;", 10));
                //向methods中添加方法,每一个接口中的方法信息,都添加到methods中
                //3.2.3
                //关注每个 MethodInfo 生成逻辑
                this.methods.add(var16.generateMethod());
            }
        }
		//将static初始化代码块对应的 MethodInfo 添加到 methods 中
        //3.2.2
        this.methods.add(this.generateStaticInitializer());
    } catch (IOException var10) {
        throw new InternalError("unexpected I/O Exception", var10);
    }
	//方法数量 和 成员变量 的数量添加限制: <= 65535
    if (this.methods.size() > 65535) {
        throw new IllegalArgumentException("method limit exceeded");
    } else if (this.fields.size() > 65535) {
        throw new IllegalArgumentException("field limit exceeded");
    } else {
        this.cp.getClass(dotToSlash(this.className));
        this.cp.getClass("java/lang/reflect/Proxy");
        var1 = this.interfaces;
        var2 = var1.length;

        for(var3 = 0; var3 < var2; ++var3) {
            var4 = var1[var3];
            this.cp.getClass(dotToSlash(var4.getName()));
        }

        this.cp.setReadOnly();
        //3.3
        //var13 var14
        ByteArrayOutputStream var13 = new ByteArrayOutputStream();
        DataOutputStream var14 = new DataOutputStream(var13);

        try {
            var14.writeInt(-889275714);
            var14.writeShort(0);
            var14.writeShort(49);
            this.cp.write(var14);
            //var14写入 public , protected , **
            var14.writeShort(this.accessFlags);
            //var14写入 类名
            var14.writeShort(this.cp.getClass(dotToSlash(this.className)));
            //var14写入 继承于 Proxy
            var14.writeShort(this.cp.getClass("java/lang/reflect/Proxy"));
            //var14写入 实现的接口的数量
            var14.writeShort(this.interfaces.length);
            Class[] var17 = this.interfaces;
            int var18 = var17.length;
            for(int var19 = 0; var19 < var18; ++var19) {
                Class var22 = var17[var19];
                //var14写入 实现的每个接口的名称
                var14.writeShort(this.cp.getClass(dotToSlash(var22.getName())));
            }
			//var14写入 成员变量的数量
            var14.writeShort(this.fields.size());
            var15 = this.fields.iterator();
            while(var15.hasNext()) {
                ProxyGenerator.FieldInfo var20 = (ProxyGenerator.FieldInfo)var15.next();
                //var14写入 每个成员变量
                var20.write(var14);
            }
			//var14写入 方法的数量
            var14.writeShort(this.methods.size());
            var15 = this.methods.iterator();
            while(var15.hasNext()) {
                ProxyGenerator.MethodInfo var21 = (ProxyGenerator.MethodInfo)var15.next();
                //var14写入 每个方法
                var21.write(var14);
            }
            var14.writeShort(0);
            //DataOutputStream var14 = new DataOutputStream(var13);
            //var14写入的所有数据,通过var13,返回byte[]
            return var13.toByteArray();
        } catch (IOException var9) {
            throw new InternalError("unexpected I/O Exception", var9);
        }
    }
}
-->
//3.2.1
//构造方法
private ProxyGenerator.MethodInfo generateConstructor() throws IOException {
	//"(Ljava/lang/reflect/InvocationHandler;)V"
    //猜的:代表构造函数的参数类型是 InvocationHandler
    //这就解释了为什么动态代理类构造参数是 InvocationHandler 实例
    ProxyGenerator.MethodInfo var1 = new ProxyGenerator.MethodInfo("<init>", "(Ljava/lang/reflect/InvocationHandler;)V", 1);
    DataOutputStream var2 = new DataOutputStream(var1.code);
    this.code_aload(0, var2);
    this.code_aload(1, var2);
    var2.writeByte(183);
    var2.writeShort(this.cp.getMethodRef("java/lang/reflect/Proxy", "<init>", "(Ljava/lang/reflect/InvocationHandler;)V"));
    var2.writeByte(177);
    var1.maxStack = 10;
    var1.maxLocals = 2;
    var1.declaredExceptions = new short[0];
    return var1;
}
//3.2.2
//static初始化代码块对应的 MethodInfo
//generateStaticInitializer能看到生成的动态代理类静态初始代码块的结构
//proxyMethods中存储的每个方法信息,都有对应的静态初始化代码;
private ProxyGenerator.MethodInfo generateStaticInitializer() throws IOException {
	ProxyGenerator.MethodInfo var1 = new ProxyGenerator.MethodInfo("<clinit>", "()V", 8);
    ***
    DataOutputStream var6 = new DataOutputStream(var1.code);
    //遍历 proxyMethods
	Iterator var7 = this.proxyMethods.values().iterator();
    while(var7.hasNext()) {
        List var8 = (List)var7.next();
        Iterator var9 = var8.iterator();
        while(var9.hasNext()) {
        	//获取到 proxyMethods 中存储的每个方法信息
            ProxyGenerator.ProxyMethod var10 = (ProxyGenerator.ProxyMethod)var9.next();
            //将每个方法信息写入 var6
            //3.2.2.1
            //codeFieldInitialization
            var10.codeFieldInitialization(var6);
        }
    }
    var6.write***
    ***
}
-->
//3.2.2.1
//codeFieldInitialization
private void codeFieldInitialization(DataOutputStream var1) throws IOException {
	//向var1写入 该方法源于哪个类
    ProxyGenerator.this.codeClassForName(this.fromClass, var1);
    //向var1写入 该方法方法名
    ProxyGenerator.this.code_ldc(ProxyGenerator.this.cp.getString(this.methodName), var1);
    //向var1写入 该方法参数长度
    ProxyGenerator.this.code_ipush(this.parameterTypes.length, var1);
    var1.writeByte(189);
    var1.writeShort(ProxyGenerator.this.cp.getClass("java/lang/Class"));
    //遍历每个方法参数
    for(int var2 = 0; var2 < this.parameterTypes.length; ++var2) {
        var1.writeByte(89);
        //向var1写入 当前参数索引值
        ProxyGenerator.this.code_ipush(var2, var1);
        **
        //向var1写入 当前参数所属的Class
        ProxyGenerator.this.codeClassForName(this.parameterTypes[var2], var1);
        **
        var1.writeByte(83);
    }
    var1.writeByte(182);
    var1.writeShort(ProxyGenerator.this.cp.getMethodRef("java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"));
    var1.writeByte(179);
    var1.writeShort(ProxyGenerator.this.cp.getFieldRef(ProxyGenerator.dotToSlash(ProxyGenerator.this.className), this.methodFieldName, "Ljava/lang/reflect/Method;"));
}

//3.2.3
//关注每个 MethodInfo 生成逻辑
//只看关键逻辑
private ProxyGenerator.MethodInfo generateMethod() throws IOException {
	String var1 = ProxyGenerator.getMethodDescriptor(this.parameterTypes, this.returnType);
    ProxyGenerator.MethodInfo var2 = ProxyGenerator.this.new MethodInfo(this.methodName, var1, 17);
    ***
    DataOutputStream var9 = new DataOutputStream(var2.code);
    ***
    //获取到成员变量h,h属于InvocationHandler
    var9.writeShort(ProxyGenerator.this.cp.getFieldRef("java/lang/reflect/Proxy", "h", "Ljava/lang/reflect/InvocationHandler;"));
    ***
    //向var9写入 方法名
    var9.writeShort(ProxyGenerator.this.cp.getFieldRef(ProxyGenerator.dotToSlash(ProxyGenerator.this.className), this.methodFieldName, "Ljava/lang/reflect/Method;"));
    //遍历方法参数
    if (this.parameterTypes.length > 0) {
        ProxyGenerator.this.code_ipush(this.parameterTypes.length, var9);
        var9.writeByte(189);
        var9.writeShort(ProxyGenerator.this.cp.getClass("java/lang/Object"));
        for(int var10 = 0; var10 < this.parameterTypes.length; ++var10) {
            var9.writeByte(89);
            ProxyGenerator.this.code_ipush(var10, var9);
            //向var9写入 当前参数类型,当前参数索引值
            this.codeWrapArgument(this.parameterTypes[var10], var3[var10], var9);
            var9.writeByte(83);
        }
    } else {
        var9.writeByte(1);
    }
    //向var9写入 执行InvocationHandler的invoke方法
    //这里就解释了生成的动态代理类,为什么每个方法内部,都是执行 InvocationHandler.invoke(Object var1, Method var2, Object[] var3)方法。
    var9.writeShort(ProxyGenerator.this.cp.getInterfaceMethodRef("java/lang/reflect/InvocationHandler", "invoke", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;"));
    ***
}

generateClassFile总结:

  1. proxyMethods 中存储了:
    • 动态代理类需实现的所有接口中的所有方法
    • Object的 hashCode,equals,toString 3个方法;
  2. proxyMethods 存储完毕开始遍历
    • 2.1:methods
      1. methods中添加 构造函数方法
      2. methods中添加 proxyMethods中的每个方法
      3. methods中添加 静态初始化代码块
    • 2.2:fields
      1. fields中添加 proxyMethods中的每个方法对应的成员变量
  3. generateConstructor 生成的构造函数,以InvocationHandler作为参数,这就解释了为什么生成动态代理类实例需要传入InvocationHandler实例。
  4. generateStaticInitializer 中对proxyMethods进行遍历,proxyMethods中每个方法都有对应的静态初始化代码。
  5. 动态代理类所有相关信息写入var14,var14和var13相关联,通过var13返回该动态代理类对应的byte数组.
  • 5.1:简略
ByteArrayOutputStream var13 = new ByteArrayOutputStream();
DataOutputStream var14 = new DataOutputStream(var13);
return var13.toByteArray();
  • 5.2:var14具体写入过程
//var14写入 public , protected , **
//var14写入 类名
//var14写入 继承于 Proxy
//var14写入 实现的接口的数量
//var14写入 实现的每个接口的名称
//var14写入 成员变量的数量
//var14写入 每个成员变量
//var14写入 方法的数量
//var14写入 每个方法

JDK动态代理[4]---ProxyGenerator生成代理类的字节码文件解析 这篇文章也是这个方法的解析,明天看一下