Java JDK 动态代理
Jakcy
Java
2021-10-28
6
原理
JDK动态代理只能代码接口不能代理类。 JDK动态代理调用了Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 方法。 通过该方法生成字节码,动态的创建了一个代理类,interfaces参数是该动态类所继承的所有接口,而继承InvocationHandler接口的类则是实现在调用代理接口方法前后的具体逻辑,下边是具体的实现:
代码
package com.yixing.demo;
import sun.misc.ProxyGenerator;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Demo1 {
static interface IHello {
String say();
}
static class Hello implements IHello {
@Override
public String say() {
return "Hello > " + this;
}
}
static class InvocationHandlerDemo implements InvocationHandler {
private IHello target;
InvocationHandlerDemo(IHello target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke begin");
try {
// 生成代理类字节码文件
System.out.println(proxy.getClass().getName());
byte[] b= ProxyGenerator.generateProxyClass(proxy.getClass().getSimpleName(),proxy.getClass().getInterfaces());
FileOutputStream out = new FileOutputStream("./"+proxy.getClass().getSimpleName()+".class");
out.write(b);
out.flush();
out.close();
System.out.println(proxy.getClass());
return method.invoke(target, args);
} finally {
System.out.println("invoke end");
}
}
}
public static void main(String[] args) {
IHello hello = new Hello();
System.out.println(hello.say());
IHello hello2 = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(), hello.getClass().getInterfaces(), new InvocationHandlerDemo(hello));
System.out.println(hello2.say());
}
}
Hello > com.yixing.demo.Demo1$Hello@5e2de80c
invoke begin
com.yixing.demo.$Proxy0
class com.yixing.demo.$Proxy0
invoke end
Hello > com.yixing.demo.Demo1$Hello@5e2de80c
生成的代理类
import com.yixing.demo.Demo1.IHello;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements IHello {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.yixing.demo.Demo1$IHello").getMethod("say");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
public $Proxy0(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 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 String say() throws {
try {
return (String)super.h.invoke(this, m3, (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);
}
}
}