jdk动态代理实现原理

本文详细解析了Java动态代理的实现原理,通过Calculator接口、CalculatorImpl实现类、CalculatorProxy代理类以及测试代码,展示了如何利用Proxy、InvocationHandler等类实现动态代理。文章进一步分析了生成的代理类源码,揭示了调用代理对象方法时的实际执行流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

jdk的动态代理即使用反射来实现,具体由Proxy、InvocationHandler等类来实现的。

具体调用过程比较难理解,但是如果看到生成的代理类就不难理解了。

代码如下:

接口类:Calculator.java

package com.yangjianzhou.javaBasics;

/**
* Created by yangjianzhou on 16-5-8.
*/
public interface Calculator {

public int add(int operator1 , int operator2);

}



实现类:CalculatorImpl.java

package com.yangjianzhou.javaBasics;

/**
* Created by yangjianzhou on 16-5-8.
*/
public class CalculatorImpl implements Calculator {

@Override
public int add(int operator1, int operator2) {
System.out.println("operator1 + operator2 = " + (operator1 + operator2));
return operator1 + operator2;
}
}



代理类:CalculatorProxy.java

package com.yangjianzhou.javaBasics;

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

/**
* Created by yangjianzhou on 16-5-8.
*/
public class CalculatorProxy {

public void executeProxy(){

Calculator calculator = new CalculatorImpl();
LogHandler logHandler = new LogHandler(calculator);
Calculator proxy = (Calculator) Proxy.newProxyInstance(calculator.getClass().getClassLoader() , calculator.getClass().getInterfaces(),logHandler);
proxy.add(2,3);
}
}

class LogHandler implements InvocationHandler{

Object obj ;

public LogHandler(Object obj) {
this.obj = obj;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.doBefore();
Object object = method.invoke(obj , args);
this.doAfter();
return object;
}

public void doBefore(){
System.out.println("log before method");
}

public void doAfter(){
System.out.println("log after method");
}
}



测试代码:TestProxy.java

package com.yangjianzhou.javaBasics;

import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;

/**
* Created by yangjianzhou on 16-5-8.
*/
public class TestProxy {

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

CalculatorProxy calculatorProxy = new CalculatorProxy();
calculatorProxy.executeProxy();
byte[] classCode = ProxyGenerator.generateProxyClass("com.yangjianzhou.javaBasics.", new Class[]{Calculator.class});
FileOutputStream fileOutputStream = new FileOutputStream("/tmp/proxy.class");
fileOutputStream.write(classCode);
fileOutputStream.close();
}
}




反编译proxy.class得到的java代码如下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.yangjianzhou.javaBasics;

import com.yangjianzhou.javaBasics.Calculator;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

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

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

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

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

public final int add(int var1, int var2) throws {
try {
return ((Integer)super.h.invoke(this, m3, new Object[]{Integer.valueOf(var1), Integer.valueOf(var2)})).intValue();
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}

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);
}
}

static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m3 = Class.forName("com.yangjianzhou.javaBasics.Calculator").getMethod("add", new Class[]{Integer.TYPE, Integer.TYPE});
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}



因此,调用proxy.add(2,3),实际上就是调用LogHandler的invoke方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值