代理模式-proxy
1.什么是代理模式
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
在实际生活中,我们经常见到这样的场景,如:租房中介、售票黄牛、婚介、经纪人、快递、事务代理、非侵入式日只监听等,这些都是代理模式的实际体现。代理模式的定义也非常简单,是指为其它对象提供一种代理,以控制对这个对象的访问。
2.代理模式的作用
代理对象在客户端和目标对象之间起到中介作用,代理模式属于结构性设计模式。使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象.
3.代理模式分类
代理模式分为两种:
1.静态代理,在运行前,通过编写代码的方式生成代理类
2.动态代理,在运行后,通过反射机制生成代理类
静态代理
1.实现步骤
1)代理者和被代理者都实现相同的接口
2)代理者包含被代理者的对象
3)创建代理对象时传入被代理对象
4)代理者执行方法时,会调用被代理者的方法,同时扩展新的功能
/**
* 手机销售
*/
public interface CellphoneSales {
/**
* 销售手机
* @param phone
*/
void sell(String phone);
}
/**
* 手机工厂
*/
public class CellphoneFactory implements CellphoneSales {
public void sell(String phone) {
System.out.println("卖了一部" + phone);
}
}
/**
* 手机商店
*/
public class CellphoneShop implements CellphoneSales{
//手机工厂对象
private CellphoneSales factory = null;
//通过构造方法传入被代理者
public CellphoneShop(CellphoneSales factory) {
this.factory = factory;
}
public void sell(String phone) {
//扩展功能
System.out.println("打广告!!!新手机,黑科技!!");
//调用原来的被代理者方法
this.factory.sell(phone);
//扩展功能
System.out.println("做售后!!!");
}
}
public class TestCellphone {
public static void main(String[] args) {
//创建手机工厂
CellphoneSales factory = new CellphoneFactory();
factory.sell("华为P40手机");
//创建商店
CellphoneSales shop = new CellphoneShop(factory);
//调用方法
shop.sell("华为P40手机");
}
}
JDK动态代理
JDK自带的,前提是:被代理类必须实现过接口。
实现步骤
1) 实现InvocationHandler接口
2)实现invoke方法
3)通过Proxy.newProxyInstance方法返回代理对象
/**
* 工厂的JDK动态代理
*/
public class JDKFactoryProxy implements InvocationHandler {
//被代理对象
private Object target;
/**
* 创建代理对象
* @param target 被代理对象
* @return 代理对象
*/
public Object createProxy(Object target){
this.target = target;
//创建代理对象 参数1:类加载器, 参数2:代理对象实现的接口,参数3:InvocationHandler的实现对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
/**
* 代理类的方法调用
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//功能扩展
System.out.println("商店帮忙打广告!!");
//调用被代理者方法
Object invoke = method.invoke(target, args);
System.out.println("商店帮忙做售后!!");
return invoke;
}
}
CGLib动态代理
需要引入CGLib依赖,它的原理是:通过反射+继承机制动态生成被代理类的子类,所以被代理类不能是final的。
实现步骤
1)引入cglib
2)实现MethodInterceptor接口
3)实现intercept方法
4)通过Ehancer返回代理对象
/**
* CGLib动态代理
*/
public class CGlibFactoryProxy implements MethodInterceptor {
//被代理对象
private Object target;
public Object createProxy(Object target){
this.target = target;
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(this.target.getClass());
//设置方法回调MethodInterceptor实现
enhancer.setCallback(this);
//返回代理对象
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//扩展
System.out.println("CGLib商店打广告!");
//调用原来方法
Object invoke = method.invoke(target, objects);
System.out.println("CGLib商店做售后!");
return invoke;
}
}