1,什么是代理模式?
GoF对代理模式的描述:
代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问[DP].
理解一下这句话:包含了三个角色(其他对象,代理,这个对象),代理存在的意义是方便其他对象控制对这个对象的访问.代理是这个对象的代理,而不是其他对象的代理.现在,我们给这三个角色起个名字,联系一下生活中的场景,其他对象可以是买火车票的人,代理可以是火车票代售点,这个对象可以是火车站;其他对象可以是租房客,代理可以是中介,这个对象可以是房东.我们使用Client表示其他对象,Proxy表示代理,RealSubject表示这个对象.Proxy是如何实现对RealSubject的代理呢?这就需要Proxy和RealSubject实现共同的接口Subject.Proxy类,保存一个RealSubject的引用,这样Proxy就可以访问到RealSubject,并且他们实现了共同的接口Subject,这样代理就可以用来代替RealSubject.
2,代理模式的分类有哪些?
静态代理和动态代理.
静态代理是代理类在程序运行前就已经存在.代理类通常是在java类中定义好的.通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类.
例子:
Proxy和Client共用的接口
public interface Shopping {
String doShopping(Long money);
}
Client.java类
public class Client implements Shopping {
@Override
public String doShopping(Long money) {
System.out.println("花了" + money + "元");
String[] goods = {"衣服", "裤子", "鞋子", "帽子"};
return Arrays.toString(goods);
}
}
Proxy.java类
public class Proxy implements Shopping {
private Shopping mBase;
public Proxy(Shopping mBase) {
this.mBase = mBase;
}
@Override
public String doShopping(Long money) {
String goods = mBase.doShopping(money);
System.out.println("代理贪污掉: " + "裤子");
String[] result = {"衣服", "鞋子", "帽子"};
return Arrays.toString(result);
}
}
TestStatic.java类(测试类):
public class TestStatic {
public static void main(String[] args){
// 普通
System.out.println("普通: ");
Shopping client = new Client();
System.out.println(client.doShopping(100L));
// 静态代理
System.out.println("静态代理: ");
Proxy proxy = new Proxy(client);
System.out.println(proxy.doShopping(100L));
}
}
运行打印结果:
普通:
花了100元
[衣服, 裤子, 鞋子, 帽子]
静态代理:
花了100元
代理贪污掉: 裤子
[衣服, 鞋子, 帽子]
动态代理是代理类在程序运行时才存在的代理方式.
例子:
创建实现了InvocationHandler接口的类ShoppingHandler.java
/**
* 调用处理器,拦截对代理类方法的调用
*/
public class ShoppingHandler implements InvocationHandler {
/**
* 调用处理器持有RealSubject的引用
*/
private Shopping mClient;
public ShoppingHandler(Shopping mClient) {
this.mClient = mClient;
}
/**
* 当我们调用代理类对象的方法时,这个“调用”会转送到invoke方法中
*
* @param o 代理类对象
* @param method 调用的是代理类中的哪个方法
* @param objects 调用代理类中的那个方法的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
if ("doShopping".equals(method.getName())) {
Long money = (Long) objects[0];
String things = (String) method.invoke(mClient, money);
System.out.println("代理贪污掉: " + "裤子");
String[] result = {"衣服", "鞋子", "帽子"};
return Arrays.toString(result);
}
return null;
}
}
测试类:
public class TestDynamic {
public static void main(String[] args) {
Shopping client = new Client();
// 获取目标对象的代理对象
/**
* 参1:ClassLoader loader, 要进行代理类的类加载器
* 参2:Class<?>[] interfaces, 被代理类实现的接口
* 参3:InvocationHandler h, 调用处理器
* 返回: 代理类
*/
Shopping proxy = (Shopping) Proxy.newProxyInstance(client.getClass().getClassLoader(),
client.getClass().getInterfaces(),
new ShoppingHandler(client));
// 通过代理调用方法
System.out.println(proxy.doShopping(100L));
}
}
测试结果:
花了100元
代理贪污掉: 裤子
[衣服, 鞋子, 帽子]
3,动态代理vs静态代理
参考资料:
1,http://blog.csdn.net/hejingyuan6/article/details/36203505