Java 监控对象字段数据的更改”;“从外面”;
假设我有一个常规的简单Java类,例如:Java 监控对象字段数据的更改”;“从外面”;,java,reflection,Java,Reflection,假设我有一个常规的简单Java类,例如: public class Foo { private int data; public int getData() { return data; } public void setData(int data) { this.data = data; } } …现在,我想追溯(即,在不更改Foo实现的情况下)做一些魔术,以便我可以监控“数据”字段的更改。如果我能监视setData
public class Foo {
private int data;
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
…现在,我想追溯(即,在不更改Foo实现的情况下)做一些魔术,以便我可以监控“数据”字段的更改。如果我能监视setData()调用,我会非常高兴
我知道我可以使用java.lang.reflect.Proxy实例和InvocationHandler做一些类似的事情。但是,只有通过代理更改数据属性(自然)时,才会涉及处理程序。据我所知,代理需要实现一个接口才能使用。因此,下面的示例可以很好地工作:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface IFoo {
public void setData(int data);
}
class Foo implements IFoo {
private int data;
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
class MyInvocationHandler implements InvocationHandler {
private final Object monitoredInstance;
public MyInvocationHandler(Object monitoredInstance) {
this.monitoredInstance = monitoredInstance;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Invoked!");
return method.invoke(monitoredInstance, args);
}
}
public class ProxyTest {
public static void main(String[] args) throws Exception {
Foo foo = new Foo();
IFoo fooProxy = (IFoo) Proxy.newProxyInstance(
Foo.class.getClassLoader(),
new Class[]{IFoo.class},
new MyInvocationHandler(foo));
fooProxy.setData(42);
System.out.println("foo data = " + foo.getData());
}
}
但是我上面的问题是需要静态定义的IFoo接口。如上所述,我正在寻找一种根本不需要修改Foo实现的解决方案
(我已经了解了如何使用Java编译器API动态创建、编译和加载像IFoo这样的接口。我可以浏览Foo.class的方法名,找到所有的“setter”,并创建一个具有这些名称的接口。不过,在了解了所有这些之后,我不确定它是否对我有任何帮助。:-)
我希望所有这些监视业务对Foo实例的用户完全透明。我的愿望是,我能最终得到一些真正苗条的东西,比如:
Foo foo = new Foo();
ObjectMonitor om = new ObjectMonitor();
om.monitor(foo);
foo.setData(42); // The ObjectMonitor should notice this.
有什么方法可以做到这一点吗?我建议你看看能做到这一点的东西。我建议你看看能做到这一点的东西。如果“实现”指的是“源代码”,也许方面可以帮助你。使用AOP,您可以向类方法中添加类似的内容,一些AOP实现可以更改类的字节码,从而确保检测到类的所有使用情况 如果字节码本身无法修改,您可能会运气不佳。如果“实现”指的是“源代码”,那么方面可能会对您有所帮助。使用AOP,您可以向类方法中添加类似的内容,一些AOP实现可以更改类的字节码,从而确保检测到类的所有使用情况
如果字节码本身无法修改,您可能会倒霉。是的,我指的是源代码。我很欣赏AOP的建议,尽管这感觉就像用象枪杀死蚊子一样。但也许没有比这更简单的方法了?@据我所知,这可能不是。你想要变魔术,而这很少是简单的——即使看起来很简单;-)是的,我指的是源代码。我很欣赏AOP的建议,尽管这感觉就像用象枪杀死蚊子一样。但也许没有比这更简单的方法了?@据我所知,这可能不是。你想要变魔术,而这很少是简单的——即使看起来很简单;-)