代理模式
代理模式:指客户端不直接调用目标对象,而是通过调用代理,间接性调用目标对象。
为什么要用代理呢?为一个对象提供一个替身,以控制对这个对象的访问。可以在目标对象基础上,增加额外功能,即扩展目标对象的功能.。
一、静态代理
静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类。
代码示例:
ComputerSell(接口)
/**
* 接口
*/
public interface ComputerSell {
void sell();
}
LenovoComputerFactory(目标对象)
/**
* 联想厂商
*/
public class LenovoComputerFactory implements ComputerSell {
@Override
public void sell() {
System.out.println("售卖了联想笔记本");
}
}
LenovoProxcy (代理)
/**
* 联想电脑代理商
*/
public class LenovoProxcy implements ComputerSell {
private ComputerSell computerSell;
//维护目标对象
public LenovoProxcy(ComputerSell computerSell) {
this.computerSell=computerSell;
}
@Override
public void sell() {
System.out.println("执行售卖sell方法前");
this.computerSell.sell();
System.out.println("执行售卖sell方法前");
}
}
测试如下:
/**
* 测试类
*/
public class MainComputerApp {
public static void main(String[] args) {
LenovoComputerFactory lenovoComputerFactory = new LenovoComputerFactory();
LenovoProxcy lenovoProxcy = new LenovoProxcy(lenovoComputerFactory);
lenovoProxcy.sell();
}
}
总结:静态代理可以在不修改目标对象功能的同时,额外扩展功能。然而代理类和目标类都必须实现同一接口,目标类多、代理类多,如果修改接口难以维护。动态代理可以避免这一缺点。
一、动态代理
动态代理基于JDK的API,也叫JDK代理,动态在内存中构建代理对象。这里我们需要目标对象和目标对象实现的接口,然后创建一个动态代理类实现InvocationHandler,重写invoke方法。
代码示例:
接口和目标对象和上面一样
/**
* 动态代理类
*/
public class MyFactorySellHandler implements InvocationHandler {
private Object taget = null;
// 维护目标对象
public MyFactorySellHandler(Object taget) {
this.taget = taget;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行售卖sell方法前");
Object res = method.invoke(taget, args);
System.out.println("执行售卖sell方法后");
return res;
}
}
创建代理对象:
这里需要引用 Proxy.newProxyInstance方法。该方法三个参数分别表示:
- ClassLoader loader表示目标对象的类加载器
- Class<?>[] interfaces表示目标对象实现的一组接口
- InvocationHandler h表示当前的InvocationHandler实现实例对象
/**
* 测试
*/
public class MainComputerApp {
public static void main(String[] args) {
LenovoComputerFactory factory = new LenovoComputerFactory();
InvocationHandler myFactorySellHandler = new MyFactorySellHandler(factory);
//代理对象
ComputerSell obj = (ComputerSell)Proxy.newProxyInstance(factory.getClass().getClassLoader(),
factory.getClass().getInterfaces(),
myFactorySellHandler);
obj.sell();
}
}