JDK Proxy 生成的代理对象源码

54 阅读1分钟

image.png

JDK Proxy 生成的代理对象源码

jdk 代理的两个核心类是 java.lang.reflect.Proxyjava.lang.reflect.InvocationHandler , 通过 java.lang.reflect.Proxy#newProxyInstance 方法获取一个代理对象,但是 jdk 的代理只能针对接口生成代理对象. 本篇内容会探究 jdk 代理的实现原理。

场景

public class JdkProxyDemo {

    interface Foo {
        void foo();
    }

    static final class Target implements Foo {
        @Override
        public void foo() {
            System.out.println("Target foo");
        }
    }

    public static void main(String[] args) throws Exception {

        Target target = new Target();

        Foo proxy = (Foo) Proxy.newProxyInstance(JdkProxyDemo.class.getClassLoader(), new Class[]{Foo.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("before --------------------------------");
                Object ret = method.invoke(target, args);
                System.out.println("after --------------------------------");
                return ret;
            }
        });

        System.out.println(proxy.getClass());

        proxy.foo();

        System.in.read();
    }
}

jdk 生成代理对象源码

该源码使用阿里巴巴 arthas 工具反编译得出。

package org.devx.spring.certified.professional.edu.course.a12;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import org.devx.spring.certified.professional.edu.course.a12.JdkProxyDemo;

final class $Proxy0 extends Proxy implements JdkProxyDemo.Foo {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy0(InvocationHandler invocationHandler) {
        super(invocationHandler);
    }

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

    public final String toString() {
        try {
            return (String)this.h.invoke(this, m2, null);
        }
        catch (Error | RuntimeException throwable) {
            throw throwable;
        }
        catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final void foo() {
        try {
            this.h.invoke(this, m3, null);
            return;
        }
        catch (Error | RuntimeException throwable) {
            throw throwable;
        }
        catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final int hashCode() {
        try {
            return (Integer)this.h.invoke(this, m0, null);
        }
        catch (Error | RuntimeException throwable) {
            throw throwable;
        }
        catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m3 = Class.forName("org.devx.spring.certified.professional.edu.course.a12.JdkProxyDemo$Foo").getMethod("foo", new Class[0]);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
            return;
        }
        catch (NoSuchMethodException noSuchMethodException) {
            throw new NoSuchMethodError(noSuchMethodException.getMessage());
        }
        catch (ClassNotFoundException classNotFoundException) {
            throw new NoClassDefFoundError(classNotFoundException.getMessage());
        }
    }
}

更多的技术原理会在系列文章的后续内容中提供。该文章会同步在微信公众号 【DevXJava】, 方便在微信客户端阅读。


DevXJava 不止于技术