Java has the
Introspector class that either uses the Reflection API or explicit information about a bean stored in a
BeanInfo object. This class provides a standard way to access the properties of JavaBeans and comes in handy if you’d like to copy properties from one bean to another in a generic way.
Suppose you’ve built an application that uses standard JavaBeans to represent business objects of your problem domain. Then you decided to expose your application as a web service that returns XML: you created a XML Schema for JAXB and generated a second model with it. Now all you would have to do is to fill the generated model and use JAXB to read/write it to your web service.
Since you’re a hacker and avoid repetitive work like the plague you write a tool that introspects your original beans and populates their properties to the generated JAXB beans and vice versa. This way you don’t have to write lots and lots of code that looks like:
// for marshalling jaxbBean.setFoo(bean.getFoo()); // for unmarshalling bean.setFoo(jaxbBean.getFoo());
You might ask why you don’t use the generated model in the first place and get rid of the old one. First of all this would be less fun and as a serious answer you probably don’t want to couple your application too tight to JAXB, because you might want to switch to another Java-to-XML binding framework (e.g. Castor) in the future.
I wrote a small class (88 LOC) that’ll copy properties from one bean to another; it uses the aforementioned
Introspector class. Although this is a pretty straight forward thing it introduces a major performance penalty.
The final class is now a product of several development cycles:
- my first version was a brute force attempt with some for loops
- the second version stored the methods of the JavaBeans in a lookup table; so it could look up the methods faster
- in addition to the second version, the third version tries to make no duplicate calls to e.g.
getClass()– these things are stored in variables now.
To evaluate the different versions, I coded a simple performance test that compares the performance of my BeanIntrospector implementation to code that does the same thing by hand, i.e. calling every getter/setter of two beans one after another.
The first chart shows a comparison of the different implementations.
This leaves no doubt that the boring solution is by far the fastest. Another thing you can notice is that tuning the code can help a lot: while the first implementation takes more than 100ms to fill 1000 JavaBeans, the tuned version takes about 40ms to do the same thing. In addition to that the final version is more readable than the brute force variant.
The second chart shows a comparison between the final implementation and doing the same thing by hand. Note that I set the y-axis to logarithmic scale.
If performance is important for your application you should explicitly copy the properties from one bean to another. If you’ve got beans with a lot of properties, write yourself a small tool that’ll generate the code for you. On the other hand if you need a fast hack you might want to use the
BeanIntrospector class I wrote or write yourself a similar solution.