BeanUtils 与 ReflectionToStringBuilder 的性能(用于 Bean 类)
我的 Web 应用程序中有大量 Java bean 类,我试图找到一种简单的方法来实现这些 bean 中的 toString()
方法。 toString()
方法将用于在整个应用程序中进行日志记录,并且应该打印 bean 中所有属性的属性-值对。
我正在尝试两种选择:
1. BeanUtils.describe()
(Apache commons-beanutils)
2. ReflectionToStringBuilder.toString()
(Apache commons-lang)
由于这是一个预计具有高流量的 Web 应用程序,因此实现必须是轻量级的,并且不应影响性能。 (内存使用、处理器使用等是主要考虑因素)。
我想知道根据上述标准,其中哪一个表现更好。据我所知,反射是一项繁重的操作,但更多细节和对这两个选项的深入了解将帮助我选择最佳解决方案。
I have a large number of Java bean classes in my web application, and I am trying to find a simple way to implement the toString()
methods in these beans. The toString()
method would be used for logging throughout the application, and should print the attribute-value pairs of all attributes in the bean.
I am trying out two alternatives:
1. BeanUtils.describe()
(Apache commons-beanutils)
2. ReflectionToStringBuilder.toString()
(Apache commons-lang)
Since this is a web application expected to have high traffic, the implementation has to be lightweight and should not impact performance. (Memory use, processor use, etc are main considerations).
I'd like to know which of these performs better according the criteria mentioned above. As far as I know, reflection is a heavy operation, but more details and insight into both these options would help me choose the optimal solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我们在对象的
toString()
方法中使用ToStringBuilder.reflectionToString()
。我们在生产环境中没有遇到过类似的问题。当然,我们很少使用 toString() 方法。我们还使用 BeanUtils.describe(),但出于其他目的。
BeanUtils
使用PropertyUtilsBean
来保留已执行内省的 Bean 的内部缓存。看起来这将给它带来比另一个更好的性能优势,但是稍微研究一下 ReflectionToString 源代码,似乎由于它最终依赖于 java.lang.Class 的实现,所以缓存在那里也发挥作用。两者看起来都是一个可行的选择,但是 BeanUtils.describe() 将返回一个属性映射,其中 ReflectionToString 将返回一个格式化字符串。我想这取决于你想对输出做什么。
我建议,如果您的应用程序严重依赖于对对象调用
toString()
,那么拥有特定的实现可能会更有利。We use
ToStringBuilder.reflectionToString()
in our objects'toString()
methods. We have not had any issues running like this in a production environment. Granted, we rarely use thetoString()
method.We also use
BeanUtils.describe()
, but for another purpose.BeanUtils
usesPropertyUtilsBean
which keeps an internal cache of beans for which it has performed introspection. It would seem that this would give it a performance advantage over the other, but a little poking around in the reflectionToString source and it seems that since it ultimately relies on the implementation ofjava.lang.Class
, caching comes into play there as well.Either looks like a viable choice, but
BeanUtils.describe()
will return a Map of properties where reflectionToString will return a formatted String. I guess it depends on what you want to do with the output.I would suggest that if your application is heavily dependent on calling
toString()
on your objects, having a specific implementation might be more beneficial.就我个人而言,我更喜欢使用 Eclipse/IntelliJ 生成 toString() 方法,然后根据需要对其进行修改(仅包括重要字段)。
右键单击->来源->生成 toString()。选择字段。完毕。
如果您担心性能,这就是我会走的路。
Personally, I prefer to generate the toString() method using Eclipse/IntelliJ and then modify it as necessary (only include important fields).
Right click -> Source -> Generate toString(). Select fields. Done.
That's the path I would go if you're concerned about performance.
请小心,因为这是基于反射的,所以速度会很慢。
在最近的一个 Web 项目中,我们的 Base 实体 toString() 方法是 ToStringBuilder.reflectionToString(this)
该方法在保存期间在 hibernate 中调用(通过 Spring Data JPA 存储库)。我们有一个相当大的带有嵌套列表的对象树,导致保存期间内存和 CPU 占用很大。
差点就毁掉了这个项目。
Be careful, as this is reflection based it will be slow.
In a recent web project our Base entity toString() method was ToStringBuilder.reflectionToString(this)
This method is called in hibernate during save (via Spring Data JPA respository). We have quite a large object tree with nested lists, leading to a large in memory and CPU hit during save.
It almost sank the project.
只需使用 IDE 中的代码生成器来生成 toString() 方法。这样您就可以避免使用反射造成的开销。在实际生产系统中,您的 toString() 方法可能会被频繁调用(100/秒),导致垃圾收集器努力工作并暂停您的 JVM。这些停顿可以是几秒或几十秒。
Just use code generator in your IDE to generate toString() method. This way you will avoid the overhead caused by using reflections. In real production system your toString() method can be called very often (100/sec) causing garbage collector to work hard and pause your JVM. These pauses can be seconds or tens of seconds.