一、范例:用生活中租房作为一个实例,用来更好的理解这个代理模式。
第一种:我们直接跟拥有房产证的房东进行租房。
第二种:中间商赚差价,我们跟中间商进行租房交易(也就是这里所说的代理),然后提供给中间商我们的信息,押金等等,然后中间商在操控我们的信息跟大房东(也就是拥有房产证的真正的房东进行租房)。
接下里我们用代码去实现这个过程:
1.创建拥有房产证的大房东的接口
package proxy;
public interface HireHouse {
// 拥有房产证的房东
public void hire();
}
2.去实现该接口完成租房
package proxy;
public class HireHouseImpl implements HireHouse {
@Override
public void hire() {
System.out.println("租房");
}
}
3.创建代理商(也就是这个代理商跟大房东达成我可以帮你往外租房的协议)
package proxy;
// 中间商赚差价
public class HireHouseProxy implements HireHouse {
// 真实角色
private HireHouse hh;
public HireHouseProxy(HireHouse hh) {
this.hh = hh;
}
@Override
public void hire() {
System.out.println("收中介费");
// 租完房
hh.hire();
// 扣押金
System.out.println("收取n++的RMB");
}
}
4.这时候就是我们这些人出现了
第一种:跟代理商完成租房
package proxy;
public class Client {
public static void main(String[] args) {
/*
实例化代理商并实现租房
*/
HireHouse hh = new HireHouseProxy(new HireHouseImpl());
hh.hire();
}
}
第二种:我们自己租
package proxy;
public class Client {
public static void main(String[] args) {
// 自己租
HireHouse hh1 = new HireHouseImpl();
hh1.hire();
}
}
二、以上这种它只能去代理租房这件事,接下来我们来通过反射实现代理任何事物(沿用租房来举例)
1.以上第一步第二步不变,接下来就是让代理商变成通用的代理商(必须实现InvocationHandler这个接口)
package dynamicProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
// 中间商赚差价,给任何接口做代理
public class HireHouseProxy implements InvocationHandler {
// 被代理的真实角色
private Object obj;
public HireHouseProxy(Object obj) {
this.obj = obj;
}
/*
*JDK的动态代理,被代理的对象必须实现接口
* 第二个参数method是被代理对象的接口方法
* 第三个参数method是被代理对象的接口方法的参数
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置工作");
Object invoke = method.invoke(obj, args);
System.out.println("后置工作");
return invoke;
}
}
2.我要去通过这个通用的代理商完成他多产品代理中的其中一个(租房)
package dynamicProxy;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
public class Client {
public static void main(String[] args) {
// 创建被代理的接口实现类的对象
HireHouseImpl hireHouse = new HireHouseImpl();
/*
* 创建代理对象
* 第一个参数获得被代理的对象的类加载器
* 第二个参数获得被代理对象的所有接口
* 第三个参数是自定义代理类的对象
* */
HireHouse hh = (HireHouse) Proxy.newProxyInstance(hireHouse.getClass().getClassLoader(), hireHouse.getClass().getInterfaces(), new HireHouseProxy(hireHouse));
hh.hire();
/*
* 还可给list做代理
* */
List list = new ArrayList();
List o = (List) Proxy.newProxyInstance(list.getClass().getClassLoader(), list.getClass().getInterfaces(), new HireHouseProxy(list));
o.add("我就是list");
}
}
最后告诫大家,好好努力自己买房,非要租房还是跟大房东交易。哈哈