概述
代理说白了就是我们说的中介,它拥有和原代理对象一模一样的功能,同时还可以增加一些额外的功能,这一点就很爽,因为这意味这我们可以对已有对象的功能做充分的扩展,所以这一模式在几乎所有的框架中都有用到,所以就更需要学习一下了。
代理模式分为两种
静态代理:代理类和被代理的类实现了同一接口或继承同一抽象类,当然也可以直接继承被代理的类
动态代理:通过反射创建目标类的对象,从而进行一系列的操作 实现InvocationHandler接口
实际工作中我们用的最多的是动态代理,这是Spring AOP的一个核心。
具体实现
静态代理
public interface House {
/**
* 带租户看房
* @param tenant
*/
void lookHouse(String tenant);
}
/**
* 房东类
* @date 2020年9月5日08:46:46
* @author liujl
*/
public class Landlord implements House {
@Override
public void lookHouse(String tenant) {
System.out.println("房东带" + tenant + "看房");
}
}
/**
* 租房中介
* @date 2020年9月5日08:47:40
* @author liujl
*/
public class HouseProxy implements House {
// 要看房首先要有钥匙(所以要持有房子的一个引用)
private House house;
public HouseProxy() {
// 默认代理房东
this.house = new Landlord();
}
public HouseProxy(House house) {
// 可以代理任何有房子的人(包括房东和中介)
this.house = house;
}
@Override
public void lookHouse(String tenant) {
this.house.lookHouse(tenant);
}
}
public class Tenant {
public static void main(String[] args) {
// 需求:我要看房,房东没空,于是找代理
String tenantName = "刘备";
// 创建一个代理对象
HouseProxy proxy = new HouseProxy();
// 输出结果:房东带刘备看房 对于租户而言,并没有见到房东,但是房子看了
proxy.lookHouse(tenantName);
}
}
动态代理
public interface House {
/**
* 带租户看房
* @param tenant
*/
void lookHouse(String tenant);
}
/**
* @date 2020年9月5日08:46:46
* @author liujl
*/
public class Landlord implements House {
@Override
public void lookHouse(String tenant) {
System.out.println("房东带" + tenant + "看房");
}
}
/**
* @date 2020年9月5日09:25:45
* @author liujl
*/
public class HandlerProxy implements InvocationHandler {
// 要代理的对象
private Object obj;
public HandlerProxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("看房前我要先了解" + args[0] + "基本要求");
method.invoke(obj, args);
System.out.println("看房后我要总结未成交的原因");
return null;
}
}
public class DtTenant {
public static void main(String[] args) {
String tenantName = "曹操";
// 创建要代理的对象
House house = new Landlord();
// 把这个对象传给代理类
InvocationHandler proxy = new HandlerProxy(house);
House houseProxy = (House)Proxy.newProxyInstance(house.getClass().getClassLoader(), house.getClass().getInterfaces(), proxy);
// 看房前我要先了解曹操基本要求
// 房东带曹操看房
// 看房后我要总结未成交的原因
houseProxy.lookHouse(tenantName);
}
}
价值
解耦合,可扩展。在不修改源代码的情况下,动态的添加新的功能。满足开闭原则
使用场景
添加日志、新增监控、事务管理、添加缓存
未完待续.....