从代理对象访问字段

Tyl*_*eat 9 java reflection proxy android dalvik

在为Android开发ORM框架时,我遇到了一个有趣的问题.我正在使用一个名为dexmaker的库进行字节码操作,这使我能够为持久对象创建代理以实现延迟加载.

代理实例具有关联InvocationHandler,使得当在代理上调用方法时,在该方法上调用该invoke方法InvocationHandler,然后在假定它被延迟加载的情况下调用代理对象的相应方法.没有什么太令人惊讶的 - 它就像Java的Proxy类,但允许我代理实际的类而不是接口(参见dexmaker的ProxyBuilder).

成为问题的部分是我也使用反射从持久对象中检索字段值 - 现在我已经引入了延迟加载 - 代理.这是我目前正在做的事情:

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);
}
Run Code Online (Sandbox Code Playgroud)

这当然适用于常规模型实例,但对于代理实例,f.get(model)不检索代理对象的字段值.相反,它返回类的构造函数中指定的默认值.代理的字段上的访问权限显然没有被截获.

我的问题是:有什么方法可以拦截通过反射对代理的成员变量进行访问?如果没有,我如何以"类似反射"的方式检索代理字段的值?

我正在考虑的一种可能的解决方法是使用反射检索然后调用字段的getter方法,但我想知道是否有更直接的解决方案.这种解决方法,如果实际上有效,则需要对象为所有持久字段设置一个getter方法 - 从OO设计的角度来看通常应该遵循这一要求,但也会迫使更多的工作进入框架的用户.

我对任何想法持开放态度.

Hak*_*rce 1

一个好的解决方案是使用 setter/getters 而不是使用 Field 类来访问字段。(我相信这不仅仅是一个解决方法)

另一方面,如果您想采用直接字段访问方法。据我所知,没有简单的方法来拦截字段访问。请检查这个问题的答案。尽管这个问题与拦截字段修改而不是阅读字段有关,但它可能会提供一些见解和方向。