什么是代理模式
代理模式为另一个对象提供一种代理以控制对这个对象的访问。
为什么使用代理模式
当处于某种原因(安全等)考虑,不希望客户直接访问某个对象时,可以提供一个代理对象来访问这个对象。或者希望跟踪某个对象中的方法调用,记录这些执行情况,这时就可以利用代理模式添加一些额外的功能,而又不破坏原有的代码。现实生活中,打官司要找的律师,明星的经纪人等也是代理模式。
另外,java EE框架Spring的AOP(面向切面编程)的原理就是动态代理。
示例
代理模式分为两种: 静态代理和动态代理。
静态代理是自己创建代理类,在编译前就已经存在.class文件,代理类和被代理类的关系在运行前就已确定。
静态代理
静态代理类图:
Express是代理类和被代理类的接口,YundaExpress是被代理类,TaobaoProxy是代理类。
Express类:
public interface Express {
void deliverExpress(String goods);
void getStateInfo(String goods);
}
YundaExpress类:
public class YundaExpress implements Express{
public void deliverExpress(String goods) {
System.out.println("韵达快递将为您寄送:" + goods);
}
public void getStateInfo(String goods) {
System.out.println("您的快递:" + goods + " 已经到目的站,正在为您配送!");
}
}
TaobaoProxy类:
public class TaobaoProxy implements Express{
private Express express;
protected TaobaoProxy(Express express) {
this.express = express;
}
public void deliverExpress(String goods) {
System.out.println("淘宝卖家已通知快递揽件:" + goods);
express.deliverExpress(goods);
}
public void getStateInfo(String goods) {
System.out.println("亲,您的快递" + goods + "快到了哟!");
express.getStateInfo(goods);
}
}
测试类:
public class TestStaticProxy {
public static void shop(String goods, Express express) {
express.deliverExpress(goods);
express.getStateInfo(goods);
}
public static void main(String [] args) {
String goods = "球衣";
shop(goods, new YundaExpress());
shop(goods, new TaobaoProxy(new YundaExpress()));
}
}
输出:
韵达快递将为您寄送:球衣
您的快递:球衣 已经到目的站,正在为您配送!
淘宝卖家已通知快递揽件:球衣
韵达快递将为您寄送:球衣
亲,您的快递球衣快到了哟!
您的快递:球衣 已经到目的站,正在为您配送!
动态代理
动态代理是运行时创建代理对象并处理所代理方法的调用。动态代理所做的所有的调用都会被重定向到单一的调用处理器上。
动态代理类图:
RealObject类是被代理类,DynamicProxy是代理类,DynamicProxyHandler是处理所有调用的处理器。
他们的调用顺序是:
Interface类:
public interface Interface {
void doSomething(String thing);
}
RealObject类:
public class RealObject implements Interface {
public void doSomething(String thing) {
System.out.println("RealObject do " + thing);
}
}
DynamicProxyHandler类:
public class DynamicProxyHandler implements InvocationHandler {
//被代理对象
private Object proxied;
public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(this.proxied, args);
}
}
DynamicProxy类:
public class DynamicProxy<T> {
public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) {
if (true) {
(new BeforeSomething()).exec();
}
return (T) Proxy.newProxyInstance(loader, interfaces, handler);
}
}
测试类Client:
public class Client {
public static void main(String [] args) {
Interface proxied = new RealObject();
InvocationHandler handler = new DynamicProxyHandler(proxied);
Interface proxy = DynamicProxy.newProxyInstance(proxied.getClass().getClassLoader(),proxied.getClass().getInterfaces(),handler);
proxy.doSomething("sing");
}
}
输出:
Before do something
RealObject do sing
代码下载:https://github.com/ByrsH/Design-Patterns/tree/master/Design%20Patterns/src/main/java/com/yrs/proxy
参考
- 《java编程思想》
- 《设计模式之禅》