-1

亲爱的,我目前正在实现一个使用大量第三方 Web 服务的 Java 客户端。为了获得性能,我只想在客户端的对象被修改(变脏)的情况下调用 webservices。

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

4

2 回答 2

2

我认为对象不是一个单一的标量值,而是一个 bean。

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

另一种选择是保留旧 bean 实例的副本并进行比较。所以实际上问题归结为比较两个 bean,这里问的是:如何一般比较整个 java bean?可能你会发现更多,一般来说有很多处理 bean 的框架。

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

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

请注意我和其他缓存人员:实际上,这是在缓存上提供类似 Cache.putIfNotEquals(key, value) 的方法的用例,这并不费力。缓存已经存储了先前的值,并且如果值发生更改,它只会调用缓存写入器(通过设置写入)。

于 2016-02-03T09:55:01.207 回答
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 接口)

缺点

  • 它不是细粒度的,所以你不会开箱即用哪些字段是脏的。通过使用自己的序列化格式有一些复杂的方法
  • 我还没有考虑过性能,但我可以想象其他方法也不是免费的,所以在这里你需要自己测试和调整方法。
于 2016-02-03T19:29:35.913 回答