我们这里使用用户租房的例子。
1、先定义一个接口,将我们委托类的要做的行为,给他抽象出来,在接口中定义一个抽象方法。
public interface ZuFang(){
//定义一个租房的方法
public void zuFang();
}
2、定义一个委托类(房东),实现租房接口
public class WeiTuo implements ZuFang{
//房东要租房子
public void zuFang(){
System.out.pringln("房东要出租房子!");
}
}
3、定义一个中介类
/*中介类需要干两件事情
1、将房东对象作为私有属性。
2、实现invoke方法。
*/
public class DynamicProxy implements InvocationHandler{
//委托类作为内置属性
Object obj;
public DynamicProxy(Object obj){
this.obj=obj;
}
public Object invoke(Object proxy,Method method,Object[] args){
/*
Class<WeiTuo> c1 = WeiTuo.class;
Method zuFang = c1.getDeclaredMethod("要调用的该类中存在的方法名");
String result = zuFang.invoke(c1.newInstance(),null);
*/
//这里通过method.invoke(反射),实际是调用的obj(也就是房东对象)的方法。
//参考上面的注释了的代码
//执行方法返回的返回值
String result= method.invoke(obj,args);
System.out.pringln("中介带客户看房!");
System.out.pringln("中间收取看房费用");
return result;
}
}
到目前为止,中介类就是代理类,委托类还是委托类。
4、调用Proxy类的newProxyInstance方法,生成代理类对象。
public class MyTest(){
public static void main(String[] args){
//先创建中介类对象,并将委托类赋值给中介类对象的属性
DynamicProxy dp=new DynamicProxy(new WeiTuo());
//必须要加这句话,不然执行不了
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
//调用Proxy.newProxyInstance方法
/**
* 参数1、接口类的类加载器
* 参数2、接口名字
* 参数3、中介类的实例对象
*/
ZuFang zfProxy=(ZuFang)Proxy.newProxyInstance(
ZuFang.class.getClassLoader(),
new Class[]{ZuFang.class,
dp
});
//代理类调用租房方法
zfProxy.zuFang();
}
}
展示测试结果
到这里,刚才的中介类就变成了委托类,新建的代理类,就是代理类。
两个静态代理的关系
动态代理的好处:
解决了静态代理的缺点,一个代理类只能代理一个委托类(动态代理不管有多少个委托类,一个代理类就能解决)。动态代理是无入侵式的代码扩展。不修改源码的情况下,增强一些功能,
动态代理的原理:我们通过Proxy.newProxyInstance()方法生成实例代理类的对象,实例代理对象调用代理方法,实际上变成了中介类调用invoke方法,中介类通过构造方法的时候赋值了内置属性,房东类,变成了中介调用我们的委托类。我们在委托类中还可以添加自己的逻辑功能代码(功能增强)。