I'm new to Spring and worked with plain Java objects where I used to make objects immutable (final fields) where made sense.
For Spring it seems that setters are preferred over constructor injection even for immutable objects.
I read in some places that this is for historical reasons regarding compatibility with EJB v2.x.
So my questions:
* is it okay to use constructor injection or should I stick to setters?
* is there a caveat using constructor injection vs. setters?
This article explains why Spring originally pushed setter injection (back in 2003.) Here is the most relevant paragraph:
Early 2003, when Spring was first published as an open source project, it primarily focused on setter injection. Other frameworks also pioneered ways of doing dependency injection and one of those was PicoContainer, which strongly focused on constructor injection. Spring maintained its focus on setter injection because at the time, we believed that the lack of default arguments and argument names for constructor arguments resulted in less clarity for developers. We however also implemented constructor injection, to be able to offer that feature to developers that wanted to instantiate and manage objects they didn't control.
They now mention using constructor injection for required dependencies. You still shouldn't use it if you have more than a handful of dependencies to inject.
Constructor injection is great for defining a very clear contract. Also when the parameters are required constructor injection will enforce this. Using setter injection in this case could lead to the user forgetting to set required properties and getting null pointers. (hence the addition of the @Required annotation) Setter injection on the other hand is especially useful for optional parameters. More common now is the annotation based injection. Here you annotate a field and reflection is used to inject the dependency. I would say this is the preferred approach now but is not covered in the blog Jeanne linked as it was made back in 2007. Also if you use Java Config (added in 3.1) some of the arguments made like the one stated below are no longer relevant.
One of the other arguments for not using constructor injection is the lack of argument names in constructors and the fact that these do not appear in the XML.