Repeat After Me: Setter Injection is a Symptom of Design Problems
I just stumbled across an article by Steve Schols in which he compares dependency injection via setter with constructor injection. And he prefers setter injection.
I don’t agree. I especially do not agree with his arguments. Lets take them one by one.
What are the problems with constructor injection?
No reconfiguration and re-injection
Why would you want to do that? One reason why many programs are so difficult to think about is that stuff changes around. Think about it. If the state of an object is defined by its constructor you just have to find the place where your object got created in order to understand how it looks like at run time. If the state can be changed through setters you have to find every place where the setter gets called AND if the program control actually came across these places AND in which order in order to understand what state your object is in.
So don’t change the state of your objects.
you could create a circular dependency using Spring. But not by using constructor-based injection
Excuse me? How is this possibly a drawback. I spent a lot of time to fix problems caused by circular dependencies. Using constructor injection prevents many circular dependencies. Absolutely a good thing.
He also quotes the spring reference documentation:
The Spring team generally advocates setter injection, because large numbers of constructor arguments can get unwieldy
Again constructor injection shows you you have a problem. I have yet to see a class that has more then three dependencies which adheres to the Single Responsibility Principle.
So if you run into problems with constructor injection congratulation! You just found a strong indication of a design problem in your application. Go ahead fix the design problem and proceed using constructor injection.
Of course there are situations where you can’t fix the design problem and in these cases setter injection is a valid workaround. But it is just that: A workaround.






Hi Jens.
I would like to react on your post.
I was accually agreeing with and quoting the spring reference documentation, so the quotes are not my own.
But what you say is true. You shouldn’t change the state or dependencies of your objects all the time during your application runtime. But for unit or integration testing this might be usefull. The same applies if you have different objects for different users in the same application. Or like SpringSource states, when usjng JMX managed beans.
What you say about circular dependencies as a bad design is true as well. You should avoid it. But there might be a situation where it is necessary or where you get a legacy component that needs to be configured. So then using constructor injection with Spring is impossible.
There are always several parties to a topic. Martin Fowler advocates construcor injection, Spring says settter injection is the best. It depends on the circumstances anx ehat works best for you and your situation.
Great post! I totally agree!
Great post (,again)! I guess I’ll have to comment a bit on the “Spring says” theme here. First, “X says” is *never* a good argument. I would never ever change my opinion on something because an arbitrary X says so. Think yourself (I don’t mean that in an offensive way), build an opinion based on reasonable arguments and follow it. If it’s completely opposite to mine – fine, there’s no right or wrong usually.
I – employee of SpringSource and member of the extended Spring team – do not read the side notes in the reference docs the way you read them. But that’s probably due to the context I read it in. I think the docs argue about the way *Spring components* use DI. They usually do use SI for two reasons: they’re usually infrastructure components that might (theoretically) be exposed through JMX and thus potentially reconfigured. Second (and I think this is the more important reason) the usually use inheritance and constructors become a PITA with inheritance. The third – and rather ancient – reason is that back in the XML days configuration through properties was slightly more readable than CI. So it’s a trade off generally and all of these arguments usually don’t come into play when you discuss application components.
I just triggered a discussion on the internal mailing list to improve the situation because I think you’re probably not the only one looking at the Spring reference docs as some kind of authority and we at least have to avoid the apparent strong position in favor of SI. Through all my consulting years I’ve advocated CI over SI for the reasons Jens outlined above with the only exception of optional dependencies.
I think Jens had a blog post quite a while ago discussing this topic in depth already, maybe he can just link this from this blog post.
Now that you mention it. I wrote about it before: http://blog.schauderhaft.de/2012/01/01/the-one-correct-way-to-do-dependency-injection/
I disagree. What’s about default configuration.
It is pretty often that field are initialized and exposed
by setters for dependency injection.
Default initialization + Setter injection = Better experience
@Maxim – definitely a valid point. But in that scenario using SI not only makes sense but also is becoming a way of communicating which dependencies are mandatory and which are optional. Jens’ key point still stays valid: you can only set up the object instance in valid state – the given dependencies plus default ones. Once you have that you further tweak the instance by potentially re-configuring it to the desired state.
All of this has the drawback that the creator will have to make sure she sets up the object correctly before handing it out as clients which might be okay but still has to be considered.
What about doubly-linked data structures like trees and lists. (parent-child, or next-prev)
each time you add an element, don’t you have to change an existing object?
Is your point not that you should never change the state of objects, but that if you’re going to change the state, do it in an encapsulated way, and not expose the details through set methods?
Hi Harry,
actually these kind of things are possible to do without mutable objects, by creating new instances with the changed references. Google ‘Persistent Datastructures’ for more information.
But in the context of this post a double linked list is just an implementation detail. If you want a list of things in you DI context I very much recommend the equivalent of:
new List(a,b,c,d)instead of
l = new List()l.add(a)
l.add(b)
l.add(c)
l.add(d)
I would agree for initialising a list.
I know that immutability is a good thing (functional programming, concurrency and all that) I guess it’s just a question of where you push the management of your state changes.
Write a factory or a builder, that uses SI, and inject the dependencies into the object to be constructed via Constructor or private fields. Still handy enough for testing purposes, yet immutable. Spring now supports fluent interfaces, so one can even use Josh Bloch’s variant of the Builder.
Thanks to Generics (almost) no hassles with inheritance.
I agree with most parts of your post. I very much like immutable objects and thus prefer constructor injection. A system, that uses dependency injection and setters to change services or anything like that during runtime, is probably a hint, that the design and the code is difficult to understand.
But there is at least one case, where setter injection is the only practical way: think about a grails application, where all services, controllers and several other components are configured using spring (this is the default, that is very easy to use). Now you can change the code of a service in your favorite IDE, save the code and just press “reload” in your browser window. Grails recompiles the service and since everything is stateless, grails can inject the new service everywhere using setter injection. This speeds up your turnaround time from minutes to a few seconds! I very much like this grails-feature!