参考https://blog.csdn.net/weixin_43005654/article/details/109317773
无论是静态代理还是动态代理,都有四大角色:
- 抽象角色:一般会使用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,一般会做一些附属操作
- 客户:访问代理对象的人
中介租房案例
首先,定义一个接口(Rent),房东类(Host)实现该接口,并输出自己房子的相关信息。
//租房
public interface Rent {
public void rent();
}
//房东
public class Host implements Rent{
public void rent() {
System.out.println("我的房子是蓝色的,准备出租房子!");
}
}
房东将房子交给中介,此时的中介相当于代理类(Proxy)
代理类在不修改被代理对象功能 (Host类的rent方法) 的基础上,可以对代理类进行扩展(增加seeHouse、fare方法)
public class Proxy implements Rent{
private Host host;
public Proxy(){ }
public Proxy(Host host){
this.host=host;
}
public void rent() {
seeHouse();
host.rent();
fare();
}
//看房
public void seeHouse(){
System.out.println("中介带你看房子");
}
}
//收费
public void fare(){
System.out.println("收中介费");
}
}
客户购房不用面对房东,只需与中介对接。
public class Client {
public static void main(String[] args) {
Host host=new Host(); //房东要出租房子
//代理,中介帮房东租房子,但是代理角色一般会有一些附属操作
Proxy proxy=new Proxy(host);
//客户不用面对房东,直接找中介租房即可
proxy.rent();
}
}
上述代码就实现了静态代理,客户只需面向代理类操作即可。
运行截图
缺点:静态代理中,每个真实对象都会拥有一个代理类,这样将会十分繁琐。
如果采用静态代理,当有100个房东时,我们将要编写100个代理类,这种处理方法明显不妥。因此我们可以使用动态代理,编写一个代理工具类,该类并未指明代理的真实对象是哪一个。
public class DynamicProxy {
public static Object getProxyInstance(Object target){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args)->{
Object result = method.invoke(target,args);
return result;
}
);
}
}
public class Client {
public static void main(String[] args) {
Rent proxyInstance1 = (Rent) DynamicProxy.getProxyInstance(
new Host1());
proxyInstance1.rent();
Rent proxyInstance2 = (Rent)DynamicProxy.getProxyInstance(
new Host2());
proxyInstance2.rent();
}
}