这几天在学习java代理,自己练手写jdk动态代理,代理类在方法前后加了输出时间语句。遇到的问题如下:
IDEA直接run运行没有问题,但debug下重复输出时间语句。Eclipse中run和debug都没有问题。
Main方法:
public class TestDynamicProxy {
public static void main(String[] args) {
IUserDao dao = new UserDao();
dao = (IUserDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(), UserDao.class.getInterfaces(), new DynamicProxyBean(dao));
dao.saveData();
}
}
动态代理类:
public class DynamicProxyBean implements InvocationHandler {
private Object target;
public DynamicProxyBean(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法执行前后 打印当前时间
System.out.println("begin:" + DateTimeEx.TimeStampToString(System.currentTimeMillis(), "yyyy-MM-dd hh:mm:ssSSS"));
Object invoke = method.invoke(target, args);
System.out.println("end:" + DateTimeEx.TimeStampToString(System.currentTimeMillis(), "yyyy-MM-dd hh:mm:ssSSS"));
return invoke;
}
}
被代理类:
public class UserDao implements IUserDao {
@Override
public int saveData() {
System.out.println("I have been saved data.");
return 1;
}
}
输出结果:
run:
debug每行调试结果:
原因:单步调试时IDEA会调用被代理类的toString()方法,代理UserDao类会代理该类的所有方法(包括toString),因此会重复输出时间。
public class DynamicProxyBean implements InvocationHandler {
private Object target;
public DynamicProxyBean(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//输出代理的方法
System.out.println("=========="+method.getName()+"=============");
//方法执行前后 打印当前时间
System.out.println("begin:" + DateTimeEx.TimeStampToString(System.currentTimeMillis(), "yyyy-MM-dd hh:mm:ssSSS"));
Object invoke = method.invoke(target, args);
System.out.println("end:" + DateTimeEx.TimeStampToString(System.currentTimeMillis(), "yyyy-MM-dd hh:mm:ssSSS"));
return invoke;
}
}
在代理类invoke方法中添加method.getName()方法后,debug结果如下: