Java JDK 动态代理

Jakcy Java 2021-10-28 6

原理

JDK动态代理只能代码接口不能代理类。 JDK动态代理调用了Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 方法。 通过该方法生成字节码,动态的创建了一个代理类,interfaces参数是该动态类所继承的所有接口,而继承InvocationHandler接口的类则是实现在调用代理接口方法前后的具体逻辑,下边是具体的实现:

代码

package com.yixing.demo;

import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Demo1 {

    static interface IHello {
        String say();
    }

    static class Hello implements IHello {

        @Override
        public String say() {
            return "Hello > " + this;
        }
    }

    static class InvocationHandlerDemo implements InvocationHandler {

        private IHello target;

        InvocationHandlerDemo(IHello target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

            System.out.println("invoke begin");
            try {

                // 生成代理类字节码文件
                System.out.println(proxy.getClass().getName());
                byte[]  b= ProxyGenerator.generateProxyClass(proxy.getClass().getSimpleName(),proxy.getClass().getInterfaces());
                FileOutputStream out = new FileOutputStream("./"+proxy.getClass().getSimpleName()+".class");
                out.write(b);
                out.flush();
                out.close();


                System.out.println(proxy.getClass());
                return method.invoke(target, args);
            } finally {
                System.out.println("invoke end");
            }
        }
    }

    public static void main(String[] args) {
        IHello hello = new Hello();
        System.out.println(hello.say());
        IHello hello2 = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(), hello.getClass().getInterfaces(), new InvocationHandlerDemo(hello));
        System.out.println(hello2.say());
    }

}

Hello > com.yixing.demo.Demo1$Hello@5e2de80c
invoke begin
com.yixing.demo.$Proxy0
class com.yixing.demo.$Proxy0
invoke end
Hello > com.yixing.demo.Demo1$Hello@5e2de80c

生成的代理类

import com.yixing.demo.Demo1.IHello;
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 Proxy implements IHello {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("com.yixing.demo.Demo1$IHello").getMethod("say");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String say() throws  {
        try {
            return (String)super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    } 
}