Java 从代理对象访问字段
在为Android开发ORM框架时,我遇到了一个有趣的问题。我正在使用一个名为字节码操作的库,它使我能够为持久对象创建代理,以实现延迟加载 代理实例有一个关联的Java 从代理对象访问字段,java,android,reflection,proxy,dalvik,Java,Android,Reflection,Proxy,Dalvik,在为Android开发ORM框架时,我遇到了一个有趣的问题。我正在使用一个名为字节码操作的库,它使我能够为持久对象创建代理,以实现延迟加载 代理实例有一个关联的InvocationHandler,这样当在代理上调用一个方法时,就会在InvocationHandler上调用invoke方法,然后调用代理对象的相应方法,假设它已被延迟加载。没什么奇怪的——它就像Java的类一样,但允许我代理实际的类而不是接口(参见dexmaker) 出现问题的部分是,我还使用反射从持久性对象检索字段值,并且——现在
InvocationHandler
,这样当在代理上调用一个方法时,就会在InvocationHandler
上调用invoke
方法,然后调用代理对象的相应方法,假设它已被延迟加载。没什么奇怪的——它就像Java的类一样,但允许我代理实际的类而不是接口(参见dexmaker)
出现问题的部分是,我还使用反射从持久性对象检索字段值,并且——现在我已经引入了延迟加载——代理。以下是我目前正在做的事情:
for (Field f : getPersistentFields(model.getClass()) {
...
Object val = f.get(model); // model is either a persistent object or a proxy for one
mapField(f, val, map);
}
这当然适用于常规模型实例,但对于代理实例,f.get(model)
不会检索代理对象的字段值。相反,它返回在类的构造函数中指定的默认值。显然,没有拦截对代理字段的访问
我的问题是:是否有任何方法可以拦截通过反射对代理的成员变量的访问?如果不是,如何以“类似反射”的方式检索代理字段的值
一个可能的解决方法是检索字段,然后使用反射调用字段的getter方法,但我想知道是否有更直接的解决方案。如果这种解决方法真的有效,它将要求对象对所有持久性字段都有一个getter方法——从OO设计的角度来看,这一要求通常应该遵循,但也会迫使框架的用户做更多的工作
我愿意接受任何想法。一个好的解决方案是使用setter/getter访问字段,而不是使用Field类。(我认为这不仅仅是一个解决办法) 另一方面,如果您想使用直接字段访问方法。据我所知,没有简单的方法可以拦截字段访问。请核对答案。尽管问题与拦截场修正有关,而不是阅读
字段,它可能提供一些见解和方向。字段是否仍在修改中?如何修改?代理字段未被修改。能否请您详细说明一下您的设计?代理类代表模型还是与模型对象有连接?@Stefan:代理代表模型。它们不是加载对象的相关模型,而是初始化为代理。然后,当代理被访问时,例如通过调用它的一个方法,
InvocationHandler
将拦截方法调用,加载实际的模型对象,并在新加载的对象上调用方法。客户端总是访问调用方法的模型吗?这个问题仅限于框架的内部?谢谢vizier。我继续并实现了第一种方法,使用getter方法访问字段。这似乎是最直接的方法,而且效果很好。