4

我正在寻找类似于Proxy 模式Dynamic Proxy Classes的东西,只是我不想在真实对象上调用方法调用之前拦截它们,而是我想拦截正在更改的属性. 我希望代理能够表示具有不同属性集的多个对象。Action Script 3 中的 Proxy 类之类的就可以了。

这是我一般想要实现的目标:

我有一个线程运行一个对象,该对象管理由程序中的其他线程移交的值列表(数字、字符串、对象),因此该类可以负责在磁盘上创建定期持久快照以进行检查点应用程序。这个持久化对象管理一个“脏”标志,表示自上一个检查点以来值列表是否已更改,并且在忙于将其写入磁盘时需要锁定该列表。

持久化器和其他组件通过通用名称识别特定项目,因此当从崩溃中恢复时,其他组件可以首先检查持久化器是否保存了最新的副本,并从中断的地方继续工作。

在正常操作期间,为了使用他们移交给持久化器的对象,我希望他们接收对代理对象的引用,该引用看起来好像是原始对象,但是每当他们更改其上的某些值时,持久化器通知并相应地采取行动,例如在实际设置实际值之前将项目或列表标记为脏。


编辑:或者,Java中是否有通用设置器(如PHP 5),即如果属性不存在则调用的方法?或者是否有一种对象可以在运行时添加属性?

4

4 回答 4

3

如果“属性”是指JavaBean 属性,即代表一个getter 和/或setter 方法,那么您可以使用动态代理来拦截set 方法。

如果您的意思是实例变量,那么没有办法 - 不是在 Java 级别上。不过,也许可以通过字节码级别的操作来完成某些事情。

实际上,最简单的方法可能是使用AspectJ并定义一个 set() 切入点(它将拦截字节码级别的字段访问)。

于 2009-01-23T20:21:20.010 回答
2

您正在寻找的设计模式是:差分执行。我相信。

差分执行是如何工作的?

是我回答的一个与此有关的问题。

但是,我可以建议您改用回调吗?您将不得不阅读有关此内容的信息,但总体思路是您可以实现在“有趣的事情”发生时激活的接口(通常称为侦听器)。比如有一个数据结构被改变。

强制性链接:

Wiki 差异执行

维基回调

好吧,这是我看到的答案。差分执行是 O(N) 时间。这真的很合理,但如果这对你不起作用,回调会。回调基本上通过将方法按参数传递给正在更改数组的类来工作。此方法将获取更改的值和项目的位置,通过参数将其传递回“存储类”并适当地更改值。所以,是的,您必须通过方法调用来支持每个更改。

我现在意识到这不是你想要的。您似乎想要的是一种方法,您可以在数组中的每个变量上提供某种侦听器,当该项目更改时将调用该侦听器。然后侦听器将更改“备份”中的相应数组以反映此更改。

本机我想不出一种方法来做到这一点。当然,您可以使用接口创建自己的侦听器和事件。这与回调基本相同,但更好看。

然后是反射...... Java 有反射,我很肯定你可以用它写一些东西来做到这一点。然而,反射是出了名的缓慢。更不用说编码的痛苦了(在我看来)。

希望有帮助...

于 2009-01-23T20:18:34.087 回答
1

我不想在调用真实对象之前拦截方法调用,而是想拦截正在更改的属性

所以事实上,你想要监控的对象不是方便的 bean,而是 C 结构的复兴。我想到的唯一方法是使用JVMTI 中的 Field Access 调用

于 2009-01-24T00:58:33.727 回答
1

我自己也想做同样的事情。我的解决方案是使用使用 Javassist 的动态代理包装器。我将生成一个实现与目标对象的类相同的接口的类,将代理类包装在原始类周围,并将代理上的所有方法调用委托给原始类,但也会触发 PropertyChangeEvent 的 setter 除外。

无论如何,我在我的博客上发布了完整的解释和代码:http: //clockwork-fig.blogspot.com/2010/11/javabean-property-change-listener-with.html

于 2010-11-13T13:24:08.090 回答