demo
public interface Person {
//寻找真爱
void findLove();
public String getSex();
public String getName();
}
@Data
public class XiaoXingXing implements Person {
private String sex="女";
private String name="小星星";
@Override
public void findLove() {
System.out.println("我叫"+this.name+",性别:"+this.sex+".我找对象的要求是:");
System.out.println("高富帅");
System.out.println("有车有房");
System.out.println("身高要求180cm,体重70kg");
}
}
@Data
public class Zhangsan implements Person {
private String sex ="男";
private String name = "张三";
@Override
public void findLove() {
}
}
public class Meipo implements InvocationHandler {
private Person target;
public Object getInstance(Person target)throws Exception{
this.target=target;
Class clazz = target.getClass();
System.out.println("被代理对象的class是:"+clazz);
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是媒婆:你的性别是:"+this.target.getSex()+"得给你找个异性");
System.out.println("-----------------------------");
method.invoke(this.target, args);
System.out.println("-----------------------------");
return null;
}
}
public class TestFindLove {
public static void main(String[] args){
try {
Person obj =(Person) new Meipo().getInstance(new XiaoXingXing());
System.out.println(obj.getClass());
obj.findLove();
//代理对象的实现原理
//1.拿到被代理对象的引用,然后获取它的接口、
//2.JDK代理 就会重新生成一个类同时实现我们给的代理对象的所实现的接口
//3.把被代理对象的引用也拿到了
//4.重新生成一个class字节码
//5.然后编译
//获取字节码内容,可以看到原理
byte[] data = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{Person.class});
FileOutputStream os = new FileOutputStream("yust5273-proxy\\src\\main\\java\\com\\yust5273\\proxy\\jdk\\$Proxy0.class");
os.write(data);
os.close();
// //简化版
// Person xiaoxingxing = new XiaoXingXing();
//
// Person obj = (Person)Proxy.newProxyInstance(xiaoxingxing.getClass().getClassLoader(), xiaoxingxing.getClass().getInterfaces(), (proxy, method, params) -> {
// System.out.println("反射前");
// //我是重点1部分 这里是每次调用代理类方法执行的代码!!! java动态代理本质就是 对原来对象 xiaoxingxing 反射
// method.invoke(xiaoxingxing, params);
// System.out.println("反射后");
// return null;
// });
// //这里调用代理类的findLove方法,实际上会执行 “我是重点1部分”的代码
// obj.findLove();
} catch (Exception e) {
e.printStackTrace();
}
}
}
验证原理,编译会动态生成一个java类,如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import com.yust5273.proxy.jdk.Person;
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 Person {
private static Method m1;
private static Method m5;
private static Method m3;
private static Method m4;
private static Method m2;
private static Method m0;
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 getSex() throws {
try {
return (String)super.h.invoke(this, m5, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String getName() 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 void findLove() throws {
try {
super.h.invoke(this, m4, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
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 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);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m5 = Class.forName("com.yust5273.proxy.jdk.Person").getMethod("getSex");
m3 = Class.forName("com.yust5273.proxy.jdk.Person").getMethod("getName");
m4 = Class.forName("com.yust5273.proxy.jdk.Person").getMethod("findLove");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
网友评论