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开发者_StackOverflow社区-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.
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 the toString()
method.
We also use BeanUtils.describe()
, but for another purpose. BeanUtils
uses PropertyUtilsBean
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 of java.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.
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.
- It takes less time than even writing the Builder code.
- It will execute faster.
- It doesn't use permgen space (reflection can tend to eat up permgen)
That's the path I would go if you're concerned about performance.
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.
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.
精彩评论