代理模式
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
按照代理的创建时期,代理类可以分为两种。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
先来个接口(JDK动态代理是基于接口的)
package proxyTest; public interface Count { void queryCount(); void updateCount(); }
package proxyTest; public class CountImpl implements Count{ @Override public void queryCount() { System.out.println("query count...."); } @Override public void updateCount() { System.out.println("update count...."); } }问题 要在查询之前之后做一些操作 比如记录日志 校验权限之类的
静态代理开始
package proxyTest; public class CountProxy implements Count { Count count; public CountProxy(Count count ) { this.count = count; } @Override public void queryCount() { System.out.println("query start...."); count.queryCount(); System.out.println("query end...."); } @Override public void updateCount() { System.out.println("update start...."); count.updateCount(); System.out.println("update end...."); } }
Count count = new CountProxy(new CountImpl()); count.queryCount(); count.updateCount();
下面介绍动态代理,其实原理是一样的
/** * JDK动态代理类 * @author zhoushiwen * */ public class CountJDKProxy implements java.lang.reflect.InvocationHandler { private Object target; /** * 绑定委托对象并返回一个代理类 * @param target * @return */ public Object bind(Object target) { this.target = target; //取得代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object o = null; System.out.println("开始。。。。"); o = method.invoke(target, args); System.out.println("结束。。。。"); return o; } }注意:JDK的代理对象必须实现接口,有一定的局限性。 cglib弥补了这一缺陷
CountJDKProxy cjp = new CountJDKProxy();
Count count = (Count) cjp.bind(new CountImpl());
count.queryCount();
count.updateCount();
spring的AOP也是利用动态代理实现的