动态代理的实现
代理
所谓代理就是给一个不具有某个功能的类增加某个目标类的功能,如下,被代理类LogHandler 增加一个Calculator 的add方法
//接口
package gn.k48.proxy;
public interface Calculator {
int add(int a, int b);
}
//实现类
package gn.k48.proxy;
public class CalculatorImpl implements Calculator {
@Override
public int add(int a, int b) {
System.out.println(a + b);
return a + b;
}
}
//被代理目标类
package gn.k48.proxy;
import sun.misc.ProxyGenerator;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class LogHandler implements InvocationHandler {
Object object;
public LogHandler(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.doBefore();
Object o = method.invoke(object, args);
this.doAfter();
return o;
}
public void doBefore() {
System.out.println("do this before");
}
public void doAfter() {
System.out.println("do this after");
}
public static void main(String[] args) throws IOException {
Calculator calculator = new CalculatorImpl();
LogHandler logHandler = new LogHandler(calculator);
Calculator proxy = (Calculator)
Proxy.newProxyInstance(
calculator.getClass().getClassLoader(),
calculator.getClass().getInterfaces(),
logHandler);
byte[] bs = ProxyGenerator.generateProxyClass("Calculator", new Class[]{proxy.getClass()});
FileOutputStream fos = new FileOutputStream("../Calculator.class");
fos.write(bs);
proxy.add(1, 2);
}
}
打印出通过Proxy.newProxyInstance生成的动态类class文件
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import com.sun.proxy..Proxy0;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class Calculator extends Proxy implements Proxy0 {
private static Method m1;
private static Method m6;
private static Method m2;
private static Method m7;
private static Method m11;
private static Method m13;
private static Method m0;
private static Method m8;
private static Method m12;
private static Method m3; //add
private static Method m5;
private static Method m10;
private static Method m4;
private static Method m9;
public Calculator(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 InvocationHandler getInvocationHandler(Object var1) throws IllegalArgumentException {
try {
return (InvocationHandler)super.h.invoke(this, m6, 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 Class getProxyClass(ClassLoader var1, Class[] var2) throws IllegalArgumentException {
try {
return (Class)super.h.invoke(this, m7, new Object[]{var1, var2});
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final Class getClass() throws {
try {
return (Class)super.h.invoke(this, m11, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void notifyAll() throws {
try {
super.h.invoke(this, m13, (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);
}
}
public final void wait() throws InterruptedException {
try {
super.h.invoke(this, m8, (Object[])null);
} catch (RuntimeException | InterruptedException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void notify() throws {
try {
super.h.invoke(this, m12, (Object[])null);
} 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[]{var1, var2});
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final Object newProxyInstance(ClassLoader var1, Class[] var2, InvocationHandler var3) throws IllegalArgumentException {
try {
return (Object)super.h.invoke(this, m5, new Object[]{var1, var2, var3});
} catch (RuntimeException | Error var5) {
throw var5;
} catch (Throwable var6) {
throw new UndeclaredThrowableException(var6);
}
}
public final void wait(long var1) throws InterruptedException {
try {
super.h.invoke(this, m10, new Object[]{var1});
} catch (RuntimeException | InterruptedException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final boolean isProxyClass(Class var1) throws {
try {
return (Boolean)super.h.invoke(this, m4, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void wait(long var1, int var3) throws InterruptedException {
try {
super.h.invoke(this, m9, new Object[]{var1, var3});
} catch (RuntimeException | InterruptedException | Error var5) {
throw var5;
} catch (Throwable var6) {
throw new UndeclaredThrowableException(var6);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m6 = Class.forName("com.sun.proxy.$Proxy0").getMethod("getInvocationHandler", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m7 = Class.forName("com.sun.proxy.$Proxy0").getMethod("getProxyClass", Class.forName("java.lang.ClassLoader"), Class.forName("[Ljava.lang.Class;"));
m11 = Class.forName("com.sun.proxy.$Proxy0").getMethod("getClass");
m13 = Class.forName("com.sun.proxy.$Proxy0").getMethod("notifyAll");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
m8 = Class.forName("com.sun.proxy.$Proxy0").getMethod("wait");
m12 = Class.forName("com.sun.proxy.$Proxy0").getMethod("notify");
m3 = Class.forName("com.sun.proxy.$Proxy0").getMethod("add", Integer.TYPE, Integer.TYPE);
m5 = Class.forName("com.sun.proxy.$Proxy0").getMethod("newProxyInstance", Class.forName("java.lang.ClassLoader"), Class.forName("[Ljava.lang.Class;"), Class.forName("java.lang.reflect.InvocationHandler"));
m10 = Class.forName("com.sun.proxy.$Proxy0").getMethod("wait", Long.TYPE);
m4 = Class.forName("com.sun.proxy.$Proxy0").getMethod("isProxyClass", Class.forName("java.lang.Class"));
m9 = Class.forName("com.sun.proxy.$Proxy0").getMethod("wait", Long.TYPE, Integer.TYPE);
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
可以看到生成的字节码是一个Proxy的子类,将在add方法中调用了Proxy的m3方法
I'm a fucKing fake coder!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2020-02-13 Spring Security学习