Java - 检测Object是否已更改/脏检测机制的框架

时间:2016-02-03 06:55:12

标签: java hibernate caching frameworks dirty-data

亲爱的我目前正在实施一个使用相当多的第三方Web服务的Java客户端。为了获得性能,我只想调用webservices,以防我客户端的对象被修改(变脏)。

不是编写一种能够检测对象是否脏的自有框架,而是存在任何可以重用并且不与其核心产品绑定的开放/通用框架(例如,hibernate)?

2 个答案:

答案 0 :(得分:1)

我用对象推测你不是指一个标量值而是一个bean。

从技术上讲,你可以做各种奇特的事情来检测bean变异,例如更改字节码并在对象字段更新时添加一些代码。

另一种选择是保留旧bean实例的副本并进行比较。 所以实际上这个问题减少了比较两个bean,这里提到了这个问题:how to generically compare entire java beans?可能你发现更多,一般来说有很多框架都在处理bean。

但是,由于您调用webservices,因此必须具有序列化对象的机制。在发送更新请求之前,您可以使用旧对象和新对象的序列化形式来比较身份。

更改通知:我不建议将更改侦听器附加到每个bean。这可能会改变您的一般性能并引入内存泄漏。还有一个事务问题:如果更新了多个bean属性,那么bean的更新何时完成?因此,无论如何你都需要在突变后进行显式调用。

请注意自己和其他缓存人员:实际上,这是一个用例,可以在缓存上提供类似Cache.putIfNotEquals(key,value)的方法,这并不是很有效。缓存存储了之前的值,如果值发生变化,它只会调用缓存编写器(在直写设置中)。

答案 1 :(得分:0)

为其他人提供一个起点如何。

    TestBean bean1 = new TestBean("AAA");
    TestBean bean2 = new TestBean("BBB");

    log.info("serialize...");
    ByteArrayOutputStream str1 = new ByteArrayOutputStream();
    ObjectOutputStream oos1 = new ObjectOutputStream(str1);
    oos1.writeObject(bean1);
    byte[] serialized1 = str1.toByteArray();
    oos1.close();

    ByteArrayOutputStream str2 = new ByteArrayOutputStream();
    ObjectOutputStream oos2 = new ObjectOutputStream(str2);
    oos2.writeObject(bean2);
    byte[] serialized2 = str2.toByteArray();
    oos2.close();

    log.info("compare");
    boolean same = Arrays.equals(serialized1, serialized2);

这种方法的优点

  • 您序列化整个对象结构,因此它支持开箱即用的复杂层次结构,您不必关心周期(父/子)
  • 您可以对要从序列化/比较中排除的成员使用“瞬态”关键字
  • 你不必在bean类中添加一些样板代码(除了类需要实现Serializable接口)

缺点

  • 它没有细粒度,所以你不要开箱哪个字段很脏。使用own serialization format
  • 有复杂的方法
  • 我还没有考虑过性能,但我可以想象其他方法也不是免费的,所以在这里你需要测试和调整自己的方法。