Home » Java » Core Java » Dependency Injection – Field vs Constructor vs Method

About Peter Daum

Peter Daum
Peter is senior Java developer in the telecommunication industry. He works in the area of business and operations support systems and is always happy to share his knowledge and experience. He is interested in everything related to Java and software craftsmanship.

Dependency Injection – Field vs Constructor vs Method

Hi, today I would like to discuss in short different ways of injecting dependencies into your classes.

In general you have the following three options for injection

  • directly into fields/attributes
  • via explicit setter methods
  • via explicit constructor parameters

 
 

Field injection

This type of injection instruments some kind of reflection mechanism for injecting the required dependencies into the class.

While this injection type has the benefit, that it removes clutter code like setter methods or constructor parameters, it has the drawback that these dependencies are invisible. If you look at the class from the outside, you will only see the public methods and may be the constructor.

Even if this gives you a very clear idea what services a class provides, it has, in my opinion, this major drawback:

When writing tests for this particular class you have to inspect the class to see what are the required dependencies and must use either invoke the DI framework, even for simple tests, or use a kind of reflection mechanism to inject the dependencies (mocked / stubbed / real).

To make it even worse, the number of incoming dependencies is hidden within the class. Of course you can use tools (JDepend, etc. pp.) that tells you the number and direction of dependencies, or have a file that specifies the injection, but you must rely on this kind of tooling or inspect the class.

Another drawback I observed is, that the chance for creating a class that has multiple responsibilities is higher than compared to the situation when using Setter or Constructor Injection.
It’s like:

Oh let’s use this fancy annotation to inject the service we need here … Few days / hours later: It’s so difficult to test this beast

Setter Injection

Setter injection instruments setter methods, one per dependency, that are used by the DI framework to inject the dependencies.

It’s a variant that makes the dependencies explicit and  gives you a clear overview of the dependencies of the particular class.

During testing it has the benefit that you mustn’t use the DI framework or reflection mechanisms but can directly set the dependencies.

The drawback of this approach is: You can construct a class that is in a state where it can’t work. This is because you can’t distinguish from the outside if a dependency is required or optional.

Constructor Injection

Constructor injection instruments the constructor of a class, which used by the DI framework to inject the dependencies. It is the other variant that makes dependencies explicit.

In opposite to the Setter Injection it prevents you to create a class in irregular state. (Of course you can pass null, but this is than a kind of cheating, isn’t it?)  So I would say, that this is the most strict variant:

Each dependency is mandatory

The benefits of this injection type are

  1. you have to read exactly one method, the constructor, to figure out what are the dependencies of this class.
  2. you create an immutable class which makes caching and so easier

The drawback here is, again, you can’t distinguish between optional and required dependencies. The constructor enforces that all fields are set.

The last variant I would like to discuss is:

Mixing Setter and Constructor Injection

This variant, I personally prefer, mixes the Setter and Constructor Injection.

This gives you:

  • the ability to distinguish between mandatory dependencies and optional on a contractual level
  • states clearly what the dependencies of a specific class are
  • enables you easily to check if a class has to much responsibilities
  • a properly configured class after construction

Testing with this kind of injection is, similar to the pure approaches, fairly simple. You don’t need the DI framework and can easily pass mocked / stubbed / real implementations into your class under test.

What to use / prefer?

This answer depends heavily on your framework / team rule / language.

But I would strongly recommend to go for one of  the explicit injection variants, because they enable you to write pure unit tests without using the dependency injection framework.

(0 rating, 0 votes)
You need to be a registered member to rate this.
8 Comments Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

8
Leave a Reply

avatar
5 Comment threads
3 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
6 Comment authors
Saeed ZarinfamPeter DaumPictorJacob Zimmermansawe Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
newest oldest most voted
Notify of
Jacob Zimmerman
Guest

If you’re following the school of keeping objects immutable, then you’ll generally want to ignore setters. Also, I TOTALLY agree about the reflection-based injection. Ugh. That mostly just leaves constructor injection. Except…
You didn’t mention the OTHER kind of method injection, where you inject the dependency into just the method that uses it. Granted, this is technically obvious and may not even be considered dependency injection by some, but it is.

Peter Daum
Guest

Hi!

Thanks for your reply.

I totally agree on both following the principle of immutable objects, constructor injection is the only survivor. And I forgot the on method-call type of dependency injection.

Cheers

sawe
Guest
sawe

for objects that are persisted to disk, the constructor injection becomes somewhat a nightmare when the objects are retrieved from the persistent store.

Jacob Zimmerman
Guest

A nightmare? Writing row mappers to do the constructor injection is not a nightmare. It’s a big tedious, but not difaculty in the slightest.

Jacob Zimmerman
Guest

Sorry about the misspellings, but JCG commenting sucks on mobile

Pictor
Guest
Pictor

– Would be interesting to get more detail to the “Mixed” approach, to understand what you really mean.
– Would be the case to add a note about “Method-call injection” approach, as quoted in the comments.
– Can you add any note (or just reply as a comment) what could be a good approach when having optional dependencies? Is the “Method-call” or “Setter” injections the best choices?

Anyway, nice article. Simple and clear!

Peter Daum
Guest
Peter Daum

Hi Pictor, thanks for your reply. I’ll write a follow up on this article to cover the points mentioned in the comments and answer the questions. But one short answer to your last question: It depends. If you are in the situation, that the callers of a method need to inject a specific additional algorithm, that must be choosen by some information outside of the boundaries of the called class / method, I would say method-injection is the way to go. If you have, on the other hand, a class that acts as an execution template and one of the… Read more »

Saeed Zarinfam
Guest

Very nice description. thanks.