以下是几个简单的类:
[code="java"]
//接口
public interface ItemMgr {
void add();
}
//实现
public class ItemMgrImpl implements ItemMgr {
public void add() {
System.out.println("Add an Item");
}
}
//处理日志
public class LogHandler implements InvocationHandler {
private Object target;
public LogHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("Log Start Write...");
Object res = method.invoke(target, args);
System.out.println("Log End Write...");
return res;
}
}
//计算方法运行时间
public class TimeHandler implements InvocationHandler {
private Object target;
public TimeHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
long start = System.currentTimeMillis();
System.out.println("starttime : " + start);
Object res = method.invoke(target, args);
long end = System.currentTimeMillis();
System.out.println("time : " + (end-start));
return res;
}
}
//测试方法
public class TestProxy {
public static void main(String[] args) throws Exception {
ItemMgr mgr = new ItemMgrImpl();
TimeHandler th = new TimeHandler(mgr);
LogHandler lh = new LogHandler(th);
ItemMgr m = (ItemMgr)Proxy.newProxyInstance(mgr.getClass().getClassLoader(),
mgr.getClass().getInterfaces(),
th);
m.add();
}
}
[/code]
[size=small]运行测试方法会抛出java.lang.IllegalArgumentException: object is not an instance of declaring class异常
我只是在计算时间外面套了一层处理日志,望指教。[/size]
//处理日志
public class LogHandler implements InvocationHandler {
//被代理对象
private Object target;
public LogHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("Log Start Write...");
//方法参数target是被代理对象
Object res = method.invoke(target, args);
System.out.println("Log End Write...");
return res;
}
}
//计算方法运行时间
public class TimeHandler implements InvocationHandler {
//被代理对象
private Object target;
public TimeHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
long start = System.currentTimeMillis();
System.out.println("starttime : " + start);
//方法参数target是被代理对象
Object res = method.invoke(target, args);
long end = System.currentTimeMillis();
System.out.println("time : " + (end-start));
return res;
}
ItemMgr mgr = new ItemMgrImpl();
//参数传递正确,mgr实现了ItemMgr 接口
TimeHandler th = new TimeHandler(mgr);
//参数传递错误, th实现了ItemMgr接口吗?
LogHandler lh = new LogHandler(th);
java的动态代理好像是不能嵌套的
jdk1.6 测试通过!设计上没什么问题
output:
starttime : 1274061353937
Add an Item
time : 16
你对代理模式的理解可能还不够。
这不是嵌套与不嵌套的问题。
TimeHandler th = new TimeHandler(mgr);
LogHandler lh = new LogHandler(th);
这里面穿进去的mgr和th是代理对象的实例,它要求代理对象和被代理对象都必须拥有相同的接口,负责是不可能实现动态代理的。这也是java提供的动态代理的一种缺陷。
spring hibernate框架中实现的代理是通过cglib这样一个包实现的,它可以要求代理对象是任意对象,不一定要和被代理对象拥有相同的接口,功能更高级.