核心类
左边是jdk类,右边是demo的类
其中 Proxy0 是动态生成的一个类,我拷贝出来的
Proxy0 --聚合–> InvocationHandler --聚合–> Plane
所以在调用 Proxy0 的方法时,就能通过 invocationHandler 分配给 Plane
核心代码
public class FlyMain {
public static void main(String[] args) {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
//InvocationHandler nullProxyHandler = new FlyTimeCountProxy(null);
InvocationHandler birdProxyHandler = new TimeCountHandler(new Bird());
InvocationHandler planeProxyHandler = new TimeCountHandler(new Plane());
Object birdProxy = Proxy.newProxyInstance(FlyMain.class.getClassLoader(), new Class[]{Fly.class}, birdProxyHandler);
Object planeProxy = Proxy.newProxyInstance(FlyMain.class.getClassLoader(), new Class[]{Fly.class}, planeProxyHandler);
((Fly)birdProxy).fly();
((Fly)birdProxy).flyDistance();
System.out.println("\n");
((Fly)planeProxy).fly();
((Fly)planeProxy).flyDistance();
}
}
public class TimeCountHandler implements InvocationHandler {
private Object target;
public TimeCountHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(proxy.getClass());
System.out.println(method.getName());
System.out.println("fly begin ...");
Object invoke = method.invoke(target, args);
System.out.println("fly end ...");
return invoke;
}
}
package com.xyy.stu.java.core.proxy.flydemo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
/**
* @Author xu_yuanyang
* @Date 2022/3/17 2:29 下午
* @Version 1.0
*/
public final class Proxy0 extends Proxy implements Fly {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m4;
private static Method m0;
public Proxy0(InvocationHandler var1) {
super(var1);
}
public final boolean equals(Object var1) {
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 void fly() {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws UndeclaredThrowableException{
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 int flyDistance() throws UndeclaredThrowableException{
try {
return (Integer)super.h.invoke(this, m4, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() {
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"));
m3 = Class.forName("com.xyy.stu.java.core.proxy.flydemo.Fly").getMethod("fly");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m4 = Class.forName("com.xyy.stu.java.core.proxy.flydemo.Fly").getMethod("flyDistance");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
核心流程时序图
https://www.processon.com/diagraming/6232e14a637689082f02a21d
FAQ
-
为什么JDK动态代理对象能代理目标对象
代理对象和目标对象都实现了相同的接口
代理对象包含了 InvocationHandler,其实现类一般聚合了被代理对象
-
为什么动态代理能代理接口的所有方法
因为代理类的所有接口实现的方法,都是通过 调用 invocation.invoke 方法, 方法Method是其中一个参数。