从代理对象访问字段

时间:2012-03-14 01:24:39

标签: java android reflection proxy 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);
}

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

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

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

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

1 个答案:

答案 0 :(得分:1)

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

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