代理模式
作用
隐藏具体实现类类,隔离委托类和客户客户
为委托类增加功能
方法
设置一个代理类,代理类调用委托类相应的方法,之后客户类只和代理类交互。
实现
静态代理
动态代理 JDK CGLIB
JDK和CGLIB对比
JDK创建快,代理效率低,依赖接口
CGLIB创建慢,代理效率高,不依赖接口
CGLIB更适合单例模式
静态代理
针对单个委托类,进行单独封装,这个委托类在内部创建(对客户隐藏)
动态代理(JDK,CGLIB)
tom要通过代理租房给顾客,tom实现LandLord接口
需要一个类来创建新的代理类 Proxy, Enhancer
都需要一个类对方法进行包装 InvocationHandler,MethodInterceptor
声明代理类实现的接口或者父类
继承InvocationHandler,重写invoke
public class MethodHandler implements InvocationHandler {
//
private final Object obj;
public MethodHandler(Object obj){
this.obj=obj;
}
// 重写invoke方法,这个方法会在method方法(这里是Tom的rent方法)执行时被调用
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK====包装");
return method.invoke(obj,args);
}
}
public void getHouseByJDK() {
// 包装方法
InvocationHandler ph = new MethodHandler(new Tom());
// 构建代理对象
LandLord proxy = (LandLord) Proxy.newProxyInstance(ph.getClass().getClassLoader(),Tom.class.getInterfaces(),ph);
Object o = proxy.rent();
System.out.println(o);
}
t
继承MethodInterceptor ,重写intercep
public class MyMethodInterceptor implements MethodInterceptor {
// 重写intercept方法,这个方法会在method方法(这里是Tom的rent方法)执行时被调用
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("CGLIB====包装");
return methodProxy.invokeSuper(o,objects);
}
}
public void getHouseByCGLIB(){
// 类似一个代理类工厂与JDK中的Proxy类似
Enhancer enhancer = new Enhancer();
// 声明代理类的父类
enhancer.setSuperclass(Tom.class);
// 回调包装后的方法,MyMethodInterceptor类似InvocationHandler
enhancer.setCallback(new MyMethodInterceptor());
// 创建代理类
Tom proxy = (Tom) enhancer.create();
Object o = proxy.rent();
System.out.println(o);
}