I used to be a huge fan of field injection.

But one day I started to question myself. Could it be possible that I have been mistaken?

Let’s find out what happened.

Can It Be Too Simple?

I was, of course, aware of the fact that field injection versus constructor injection versus setter injection is a somewhat hot topic.

I was also aware of pros and cons of each approach. The problem was that those arguments did not resonate to me on a deeper level.

The benefits of each approach seemed clear and a bit too academic at the same time. Maybe I was not ready to really understand them yet.

To make matters worse, I really thought that I could get the good stuff of field injection and all the bad stuff would magically disappear.

I agree. I was an arrogant ass.

Nevertheless, I continued using field injection. Why? Let’s find out.

I have created a service class which uses field injection. Its source code looks as follows:

1@Service
2public class PersonServiceImpl implements PersonService {
3
4	@Autowired
5	Private PersonRepository repository;
6
7}

Now, the reason why I preferred field injection over constructor injection was that it looks a lot simpler than constructor injection. The same service class which uses constructor injection looks as follows:

 1@Service
 2public class PersonServiceImpl implements PersonService {
 3
 4	private final PersonRepository repository;
 5
 6	@Autowired
 7	public PersonServiceImpl(PersonRepository repository) {
 8		this.repository = repository;
 9	}
10}

It does not look very clean or elegant. Right?

Wait, it gets even better. What if I add some dependencies to my service class?

If I use field injection, my service class will still look clean:

 1@Service
 2public class PersonServiceImpl implements PersonService {
 3
 4	@Autowired
 5	private PersonRepository repository;
 6
 7	@Autowired
 8	Private ServiceA serviceA;
 9
10	@Autowired
11	Private ServiceB serviceB;
12}

On the other hand, if I use constructor injection, the source code of my service class looks as follows:

 1@Service
 2public class PersonServiceImpl implements PersonService {
 3
 4	private final PersonRepository repository;
 5
 6	private final ServiceA serviceA;
 7
 8	private final ServiceB serviceB;
 9
10	@Autowired
11	public PersonServiceImpl(PersonRepository repository, ServiceA serviceA, ServiceB serviceB) {
12		this.repository = repository;
13		this.serviceA = serviceA;
14		this.serviceB = serviceB;
15	}
16}

Pretty awful. Right?

My biggest problem with the constructor injection was that the constructors become very messy if my class has many dependencies.

Then I read this tweet by Oliver Gierke (Read the whole discussion):

Field injections is evil… hides dependencies, instead of making them explicit.

I started thinking about this tweet and and something clicked inside me. I understood that because it was so easy to add new dependencies to my classes in a “clean and elegant” way, I skipped a vital step.

It Is a Sign

When I used field injection and I needed to add a new dependency to my class, I followed these steps:

  1. Add a new field to the class and annotate it with the @Autowired annotation.
  2. Write the code which uses the added dependency.

This approach seemed clean and elegant but sadly I had misunderstood one very important thing. I thought that constructor injection makes constructors look messy and ugly. That was a huge mistake.

A messy constructor is a sign. It warns me that my class is becoming a monolith which is a jack of all trades and a master of none. In other words, a messy constructor is actually a good thing. If I feel that the constructor of a class is too messy, I know that it is time to do something about it.

I know that field injection and constructor injection have other differences as well. However, for me, my hatred of messy constructors is the most important one because it guided me to study and understand the other differences (the one’s that matter).

I hope that it will do the same for you.

Differences that Matter

I am not going to write about the differences of field injection, setter injection, and constructor injection. Instead, I will give you links to blog posts which I have found interesting and useful.

These blog posts are:

Did I miss something?

If you are using Spring Framework, and you want to cure the disease called field injection, you should take a look at Ninjector.