参考:Spring开发指南(作者:夏昕)
-------------------------------------------------------------------------------------------------------------------------------
在Spring开发指南(作者:夏昕)的论述中提到了Java的动态代理,按照作者的说法,Dynamic Proxy是JDK 1.3版本中新引入的一种动态代理机制。它是Proxy模式的一种动态实现版本。
下面,用代码来说明一下Java动态代理。
首先,被代理的类必须是实现某个接口的。我们现在定义接口——计算器接口:
package test.quqtalk.dynamicproxy; /** * 计算器接口 * @author Administrator * */ public interface CalculatorInterface { public int add(int arg1, int arg2); }
然后,是接口的实现——计算器:
package test.quqtalk.dynamicproxy; /** * 计算器实现 * @author Administrator * */ public class CalculatorImpl implements CalculatorInterface { /** * 返回两个整数的和 */ public int add(int arg1, int arg2) { return arg1 + arg2; } }
最后,是代理的实现。这里需要实现InvocationHandler接口,假设我们这个代理的作用是在调用add函数前后记录时间点。我们叫LogHandler。
package test.quqtalk.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 计算器代理 * * @author Administrator * */ public class LogHandler implements InvocationHandler { Log log = LogFactory.getLog(LogHandler.class); SimpleDateFormat sdf= new SimpleDateFormat("yyyy-dd-MM hh:mm:ss"); Object obj_orgin; /** * 传入被代理对象,返回代理对象 * * @param obj,被代理对象 * @return 代理对象 */ public Object bind(Object obj) { this.obj_orgin = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj .getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("add")) { int ret = 0; // 在invoke前记录日志 log.info("before add time is " + sdf.format(new Date())); ret = (Integer) method.invoke(obj_orgin, args); // 在invoke后记录日志 log.info("after add time is " + sdf.format(new Date())); return ret; } else { return method.invoke(obj_orgin, args); } } }
测试main函数:
public static void main(String[] args) {
CalculatorInterface c = (CalculatorInterface) new LogHandler()
.bind(new CalculatorImpl());
System.out.println("result is " + c.add(1, 1));
}
控制台输出结果:
16:59:38,531 INFO [main] test.quqtalk.dynamicproxy.LogHandler (LogHandler.java:41) - before add time is 2009-13-05 04:59:38
16:59:38,531 INFO [main] test.quqtalk.dynamicproxy.LogHandler (LogHandler.java:44) - after add time is 2009-13-05 04:59:38
result is 2