实现动态代理
1、接口:
public interface Person {
void rent();
}
2、
public class RentPersonimplements Person{
@Override
public void rent() {
System.out.println("我要租房子:");
}
}
3、
public class RentProxyimplements InvocationHandler {
private Objecttarget;
public ObjectRentProxy (Object target){
this.target = target;
Object instance = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
return instance;
}
@Override
public Objectinvoke(Object target, Method method, Object[] args)throws Throwable {
System.out.println("填写身份信息");
Object invoke = method.invoke(this.target, args);
System.out.println("签合同");
return invoke;
}
}
public class TestProxy{
public static void main(String[] args) {
Person o =(Person)new RentProxy().RentProxy(new RentPerson());
o.rent();
}
}
具体的原理,请编译生成的类$Proxy0 ,具体操作如下:
在测试类Main方法里面加入如下代码:
byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{Person.class});
File file =new File("D:/$Proxy0.class"); // 生成位置和文件名称
FileOutputStream outputStream =new FileOutputStream(file);
outputStream.write(bytes);
outputStream.close();
将$Proxy0.class 文件用idea 反编译 获取如下代码:
从以上代码可以看到,有一个构造方法、4个普通方法和一个静态代码块;其中equals、toString、hashCode这三个方法是每个类均有的,是继承Object类的,其中有一个方法是我们自己写的接口里面的,rent();
public final void rent() {
super.h.invoke(this, m3, (Object[])null);
}
this:当前对象;
m3是什么呢? 从以上的类可以看到时一个方法,即我们自己写的rent() 方法;
static{
m3 = Class.forName("com.travelsky.monitor.member.service.Person").getMethod("rent");
}