代理模式
代理模式旨在为服务类与客户类之间插⼊其他功能,插⼊的功能对于调⽤者是透明的,起到伪装控制的作⽤。
代理模式的两个设计原则:代理类 与 委托类 具有相似的⾏为(共同);代理类增强委托类的⾏为
静态代理
代理的三要素
有共同的⾏为——接口;目标类——实现行为;代理类——实现⾏为 增强⽬标对象⾏为
静态代理的实现
定义共同的行为
public interface Marry {
public void toMarry();
}
目标类
/**
* 静态代理 ——> ⽬标对象
*/
public class You implements Marry {
// 实现⾏为
@Override
public void toMarry() {
System.out.println("我要结婚了...");
}
}
代理类
/**
* 代理类
*/
public class MarryCompanyProxy implements Marry{
private Marry obj;
public MarryCompanyProxy(Marry obj){
this.obj = obj;
}
@Override
public void toMarry() {
System.out.println("订酒店");
System.out.println("准备婚车");
System.out.println("布置现场");
//目标类
obj.toMarry();
System.out.println("司仪开始宣告");
System.out.println("打扫清理现场");
}
}
测试
// ⽬标对象
You you = new You();
// 构造代理⻆⾊同时传⼊真实⻆⾊
MarryCompanyProxy marryCompanyProxy = new MarryCompanyProxy(you);
// 通过代理对象调⽤⽬标对象中的⽅法
marryCompanyProxy.toMarry();
动态代理
JDK动态代理
接口
public interface RentCar {
public void toRentCar();
}
目标类
public class MrLi implements RentCar {
@Override
public void toRentCar() {
System.out.println("找到车辆,付押金");
}
}
代理类
public class JdkproxyFactory {
public Object getProxyBean(Object obj){
Class clazz =obj.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("筛选车型");
//目标类 OldMa的行为方法执行
Object ret = method.invoke(obj, args);
System.out.println("清理汽车");
System.out.println("保养车");
return ret;
}
});
}
}
CGLIB动态代理
目标类
public class OldLi {
public void toRentHouse() {
System.out.println("看房,签合同");
}
}
代理类
public static Object getProxyBean(Object obj ){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass());
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("骑着小电驴带顾客看房");
//调用目标类的方法
Object invoke = method.invoke(obj, objects);
System.out.println("打扫卫生,供网供电");
return invoke;
}
});
return enhancer.create();
}
}
测试
public class Starter {
public static void main(String[] args) {
//目标类
OldLi oldLi = new OldLi();
OldLi proxyBean = (OldLi) CglibProxyFactory.getProxyBean(oldLi);
proxyBean.toRentHouse();
}
}
JDK代理与CGLIB代理的区别
JDK动态代理实现接⼝,Cglib动态代理继承思想
JDK动态代理(⽬标对象存在接⼝时)执⾏效率⾼于Ciglib
如果⽬标对象有接⼝实现,选择JDK代理,如果没有接⼝实现选择Cglib代理
代理模式实现分类以及对应区别
- 静态代理:⼿动为⽬标对象制作代理对象,即在程序编译阶段完成代理对象的创建
- 动态代理:在程序运⾏期动态创建⽬标对象对应代理对象。
- jdk动态代理:被代理⽬标对象必须实现某⼀或某⼀组接⼝ 实现⽅式 通过回调创建代理对象。
- cglib 动态代理:被代理⽬标对象可以不必实现接⼝,继承的⽅式实现。
动态代理相⽐较静态代理,提⾼开发效率,可以批量化创建代理,提⾼代码复⽤率。