ITPub博客

首页 > 数据库 > 数据库开发技术 > 揭开 JDK Proxy 生成代理对象的面纱

揭开 JDK Proxy 生成代理对象的面纱

原创 数据库开发技术 作者:DevXTalk 时间:2023-01-31 21:36:30 0 删除 编辑

JDK Proxy 生成的代理对象源码

jdk 代理的两个核心类是 java.lang.reflect.Proxy 和 java.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 不止于技术

原文作者:DevXTalk;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2019-03-23

  • 博文量
    178
  • 访问量
    82612