理解jdk动态代理

jdk的动态代理依赖接口,需要被代理对象实现了一个接口。 jdk的动态代理主要分为3部分

1、被代理对象:实际去执行对象;

2、InvocationHandler:生成代理对象,在调用真实对象前后做一些功能增强。比如redis释放连接,统计方法时延等;

3、代理对象:这个对象是在jvm运行期间生成的,可以通过sun.misc.ProxyGenerator#generateProxyClass(java.lang.String, java.lang.Class[]) 生成代理对象的字节码文件,然后反编译工具查看代理类的代码。

 

调用顺序依次为

1.生成代理对象;

2.调用代理对象方法;

3.调用java.lang.reflect.InvocationHandler#invoke,传入Method对象;

3.InvocationHandler通过反射调用真实对象。

理解jdk动态代理_第1张图片

 

伪代码:

package org.example.demo;

public interface MyInterface {
    void doSth();
}

 

package org.example.demo;

public class TargetClass implements MyInterface {

@Override
public void doSth() {
    System.out.println("target object execute.");
    }
}
package org.example.demo;

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

public class ProxyInvocationHandler implements InvocationHandler {

    private MyInterface targetClass;

    private ProxyInvocationHandler(MyInterface targetClass) {
        this.targetClass = targetClass;
    }

    public static MyInterface getInstance() {
        return (MyInterface) Proxy.newProxyInstance(ProxyInvocationHandler.class.getClassLoader(),
                new Class[]{MyInterface.class}, new ProxyInvocationHandler(new TargetClass()));
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("start to invoke target object.");
        method.invoke(targetClass, args);
        System.out.println("end to invoke target object.");
        return null;
    }
}

 

 

package org.example.demo;

import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;

public class Demo {

    public static void main(String[] args) {
        ProxyInvocationHandler.getInstance().doSth();

        generateProxyClass("ProxyClass", TargetClass.class.getInterfaces(),
                Objects.requireNonNull(TargetClass.class.getClassLoader().getResource("")).getPath().substring(1));

    }


    private static void generateProxyClass(String className, Class[] interfaces, String pathdir) {
        byte[] classFile = ProxyGenerator.generateProxyClass(className, interfaces);
        Path path1 = Paths.get(pathdir);
        if (!path1.toFile().exists()) {
            path1.toFile().mkdirs();
        }
        String path = pathdir + className + ".class";
        try (FileOutputStream fos = new FileOutputStream(path)) {
            fos.write(classFile);
            fos.flush();
        } catch (Exception e) {
        }
    }
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import org.example.demo.MyInterface;

public final class ProxyClass extends Proxy implements MyInterface {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public ProxyClass(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 void doSth() throws  {
        try {
            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);
        }
    }

    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("org.example.demo.MyInterface").getMethod("doSth");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

 

你可能感兴趣的:(java)