Java – the best way to initialize a bean


In spring you can initialize a bean by having the applicationContext.xml invoke a constructor, or you can set properties on the bean. What are the trade offs between the two approaches? Is it better to have a constructor (which enforces the contract of having everything it needs in one method) or is it better to have all properties (which gives you flexibility to only inject selectively for example when unit testing.)

What are the trade offs (between writing a bean that uses a constructor to establish it's initial state, or using properties and perhaps an afterProperties() method) ?

Best Solution

I'm not sure there is a "best" way to initialize a bean. I think there are pros and cons to each, and depending on the situation, one or the other might be appropriate. This certainly isn't an exhaustive list, but here are some things to consider.

Using a constructor allows you to have an immutable bean. Immutable objects are good if you can fit them in your design. They don't require copying, serialized access or other special handling between threads. If you have setters, your object isn't immutable. Using a constructor also ensures the object is properly initialized. After the constructor finishes, the object is valid. If your object requires the use of setters to initialize it, it's possible to have an invalid object.

On the other hand, using constructors often leads to a telescoping problem. Often times you'll need many different constructors, most of which will be a superset of another constructor. Often times these are for convenience. For instance:

public class Person {
  public Person(String name) { ... }
  public Person(String name, String phone) { ... }
  public Person(String name, String phone, String email) { ... }

One alternative to this that I very much like is the so called "enhanced" builder pattern presented by Josh Bloch at JavaOne. You can see this in his book "Effective Java, Second Edition". If you look at the way the pattern is used, it will also solve your "afterProperties" method issue. The builder pattern will guarantee the object is correctly initialized.

Here is an additional blog post discussing the pattern:

I'm not sure this fits into your spring requirement, but in general, I'm a big fan of builder.