8

我的 Web 应用程序中有大量 Java bean 类,我正在尝试找到一种简单的方法来实现toString()这些 bean 中的方法。该toString()方法将用于整个应用程序的日志记录,并且应该打印 bean 中所有属性的属性值对。

我正在尝试两种选择:
1. BeanUtils.describe()(Apache commons-beanutils)
2. ReflectionToStringBuilder.toString()(Apache commons-lang)

由于这是一个预计会有高流量的 Web 应用程序,因此实现必须是轻量级的,并且不应影响性能。(内存使用、处理器使用等是主要考虑因素)。

我想知道根据上述标准,其中哪些表现更好。据我所知,反射是一项繁重的操作,但更多细节和对这两个选项的深入了解将帮助我选择最佳解决方案。

4

4 回答 4

11

我们ToStringBuilder.reflectionToString()在对象的toString()方法中使用。我们在生产环境中没有遇到过这样的问题。当然,我们很少使用这种toString()方法。

我们也使用BeanUtils.describe(),但用于另一个目的。BeanUtils使用PropertyUtilsBean它保留已执行自省的 bean 的内部缓存。看起来这会给它一个性能优势,但在反射ToString 源中有点摸索,似乎因为它最终依赖于 的实现java.lang.Class,缓存也在那里发挥作用。

两者看起来都是一个可行的选择,但BeanUtils.describe()会返回一个属性映射,其中reflectionToString 将返回一个格式化的字符串。我想这取决于你想对输出做什么。

我建议,如果您的应用程序严重依赖于toString()对您的对象的调用,那么有一个特定的实现可能会更有益。

于 2011-04-14T00:05:43.437 回答
10

就个人而言,我更喜欢使用 Eclipse/IntelliJ 生成 toString() 方法,然后根据需要对其进行修改(仅包括重要字段)。

右键单击-> 源-> 生成 toString()。选择字段。完毕。

  1. 它甚至比编写 Builder 代码花费的时间更少。
  2. 它将执行得更快。
  3. 它不使用 permgen 空间(反射可能会消耗 permgen)

如果您担心性能,这就是我要走的路。

于 2011-04-14T05:05:57.377 回答
2

小心,因为这是基于反射的,它会很慢。

在最近的一个 Web 项目中,我们的 Base 实体 toString() 方法是 ToStringBuilder.reflectionToString(this)

在保存期间(通过 Spring Data JPA 存储库)在休眠中调用此方法。我们有一个带有嵌套列表的相当大的对象树,导致保存期间内存和 CPU 占用很大。

差点把这个项目搞砸了。

于 2014-07-04T11:08:11.087 回答
-1

只需在 IDE 中使用代码生成器来生成 toString() 方法。这样,您将避免使用反射造成的开销。在实际生产系统中,您的 toString() 方法可能会被非常频繁地调用(100/秒),从而导致垃圾收集器努力工作并暂停您的 JVM。这些停顿可以是几秒钟或几十秒钟。

于 2011-10-27T00:41:00.137 回答