参考: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