Proxy代理模式分为静态代理和动态代理。
一.静态代理
代理顾名思义就是替代,一类对象替代另一类对象去做一件事。那么一件事就是两个类对象都会做的,所以这一件事即被定义成接口,而另一个类需要在做这件事时有额外的作为,不然这个类就没有存在意义了。
一般Proxy静态类是用来扩展现有系统的,比如售票系统原代码中已经有了一个火车票售票员类TrainTicketSaler,这个售票员只能在卖火车站窗口卖票。现在增加售票代理点,代售售票员TicketSalerProxy可以答复顾客购买成功啦,只不过她不是在火车站窗口卖的。
所以类图如下:
二.动态代理
静态代理有一个最大的缺陷:接口与代理类是1对1的,有多个接口需要代理,就需要新建多个代理类,繁琐,类爆炸。
例如,当电影票也需要代理卖出时回复顾客出票成功这一服务,则创建的静态代理类图如下所示:
在静态代理的基础上,不进行代理类的定义,而是创建代理接口,交给Proxy工厂去创建接口对应的对象。
java1.8中的动态代理已经实现了Proxy工厂,你只需要提供代理处理类就可以在代码编译后创建对应的代理类。
附上一个代理处理器对应多个被代理类的代码:
/**
* @author Luolanjiao
* @date 2019/3/4
*/
public class ProxyMain {
public static void main(String[] args) {
// Saler tickSaler = new TrainTickSaler();
Saler tickSaler = new CinemaTickeSaler();
TickSalerHandler tickSalerHandler= new TickSalerHandler(tickSaler);
Saler tickProxy = (Saler) Proxy.newProxyInstance(Saler.class.getClassLoader(), new Class[]{Saler.class}, tickSalerHandler);
tickProxy.sale();
}
}
public class TrainTickSaler implements Saler{
@Override
public void sale(){
System.out.println("您正在火车站购买火车票");
}
}
public class CinemaTickeSaler implements Saler {
@Override
public void sale() {
System.out.println("您在电影院购买电影票");
}
}
public class TickSalerHandler implements InvocationHandler {
private Object tickSaler;
public TickSalerHandler(Object tickSaler){
this.tickSaler=tickSaler;
}
void ask(){
System.out.println("你的票已买好了。");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
method.invoke(tickSaler,args);
ask();
return null;
}
}
public interface Saler {
void sale();
}
注意:动态代理只能针对interface,不然会报错:
com.example.coredemo.jdk.reflect.InvocationHandlerProxyee is not an interface
源码: