设计模式之动态代理模式
代理模式:
Provide a surrogate or placeholder for another object to controlaccess to it(为其他对象提供一种代理以控制对这个对象的访问)。使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象、创建开销 大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能。
代理模式相关内容详见本人之前文章:http://www.cnblogs.com/zhaoww/p/5082035.html
动态代理:
下面贴出一个简单的关于日志的代理代码:
1 public class MessageDaoLoggingProxy { 2 3 private MessageDao target; 4 //日志 5 private static Logger logger = Logger 6 .getLogger(MessageDaoLoggingProxy.class); 7 8 public MessageDaoLoggingProxy(MessageDao target) { 9 super(); 10 this.target = target; 11 } 12 13 public MessageDao getLoggingProxy() { 14 MessageDao proxy = null; 15 // 代理对象由哪个类加载器加载 16 ClassLoader loader = target.getClass().getClassLoader(); 17 // 代理对象类型,即包含哪些方法 18 Class<?>[] interfaces = new Class[] { MessageDao.class }; 19 // 调用方法时执行的方法 20 InvocationHandler h = new InvocationHandler() { 21 @Override 22 public Object invoke(Object proxy, Method method, Object[] args) 23 throws Throwable { 24 String methodName = method.getName(); 25 26 if (args == null) { 27 logger.info("Method: " + methodName + " || Params: null"); 28 } else { 29 logger.info("Method: " + methodName + " || Params: " 30 + Arrays.asList(args)); 31 } 32 Object result = method.invoke(target, args); 33 34 logger.info("Method: " + methodName + " || Results: " + result); 35 return result; 36 } 37 }; 38 39 proxy = (MessageDao) Proxy.newProxyInstance(loader, interfaces, h); 40 41 return proxy; 42 } 43 44 }
当上一层代码需要使用代理的目标时,需要先将创建此目标对象,再通过代理类的getLoggingProxy()方法即可。
1 MessageDao target = new MessageDaoImpl(); 2 //日志代理 3 MessageDao messageDao =new MessageDaoLoggingProxy(target).getLoggingProxy();
本例中我是用内部类的方式实现InvocationHandler,当然同样可以用实现InvocationHandler接口的方式。