为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
?
抽象主题接口(Count):声明真实对象和代理对象的共同接口;
代理类:代理对象角色内部含对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实类:定义了代理角色(proxy)所代表的具体对象。
抽象接口,代理类与真实类共同实现的接口。此接口定义了两个操作,查询与更新操作。
class="java">public interface Count { public void queryCount(); public void updateCount(); }
?
真实类,实现了抽象接口。
public class CountImpl implements Count { public void queryCount() { System.out.println("query the count..."); } public void updateCount() { System.out.println("update the count..."); } }
?
?代理类,将真实类中每个操作加上事务。
public class CountProxy implements Count{ private Count count; public CountProxy(Count count) { this.count = count; } public void queryCount() { System.out.println("before transcation..."); count.queryCount(); System.out.println("after transcation..."); System.out.println(); } public void updateCount() { System.out.println("before transcation..."); count.updateCount(); System.out.println("after transcation..."); System.out.println(); } }
?
测试类
public class Test { public static void main(String[] args) { Count count = new CountImpl(); Count proxy = new CountProxy(count); count.queryCount(); count.updateCount(); System.out.println(); System.out.println("...proxy start..."); proxy.queryCount(); proxy.updateCount(); } }
?
结果
query the count... update the count... ...proxy start... before transcation... query the count... after transcation... before transcation... update the count... after transcation...
?
原理:在程序运行时,运用反射机制动态创建而成。
创建抽象接口。
?
public interface Count { public void queryCount(); public void updateCount(); }
?
真实类,实现了抽象接口。
public class CountImpl implements Count { public void queryCount() { System.out.println("query the count..."); } public void updateCount() { System.out.println("update the count..."); } }
?
代理类,将真实类中每个操作加上事务。
public class CountProxyFactory implements InvocationHandler { private Object target; public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("before transcation..."); result = method.invoke(target, args); System.out.println("after transcation..."); System.out.println(); return result; } }
?
测试类。
public class Test { public static void main(String[] args) { Count count = new CountImpl(); Count proxy = (Count)new CountProxyFactory().bind(count); proxy.queryCount(); proxy.updateCount(); } }
?
运行结果。
before transcation... query the count... after transcation... before transcation... update the count... after transcation...
?
动态代理的应用很广,比如Spring AOP和多客户端的socket网络连接等。