Several Ways to do Dependency Injection in Java

Ahmad Kamil Almasyhur
4 min readMar 30, 2019
source: https://www.toptal.com

What is Dependency Injection?

Dependency Injection(DI) is a way to decouple a tight couple object, we want to decrease the coupling between objects, and we want to increase the cohesion of in an object. Dependency Injection implemented in 4 different ways, they are Constructor Injection, Setter Injection, Interface Injection, and the last one in Field Injection. But before we talk about how to implemented the Dependency Injection, let me show you an example about high couple object. This is the example of high couple object:

** Highly Coupled Object
public class Message {
private ObjectOne objectOne = new ObjectOne();
private ObjectTwo objectTwo = new ObjectTwo();
private ObjectThree objectThree = new ObjectThree();
public Message(){
}
...
}

in this Message class, we know that message is really need that ObjectOne and ObjectTwo to run, so it’s called that Message is highly coupled to ObjectOne and ObjectTwo. If we want to break that dependency, and make them as low coupled and High Cohesion, then what we should use in Dependency Injection. several ways that DI do to decoupled that highly coupled object are:

1. Constructor Injection

** Constructor Injectionpublic class Message {
private ObjectOne abstractObject;
public Message(ObjectOne implementedObject){
this.abstractObject = implementedObject;
}
...
}

What we do here, we decouple the object by removing the dependency of ObjectOne to be an argument inside class constructor, by giving the contract from ObjectOne (ObjectOne should be abstract class/interface, that being inheritance or implemented by implementedObject).

2. Setter Injection

** Setter Injectionpublic class Message {
private ObjectOne abstractObject;
public Message(){
}
public void setAbstractObject(ObjectOne implementedObject){
this.abstractObject = implementedObject;
}
...
}

so, what we do here, we decouple the ObjectOne dependency like we do in Constructor Injection, we remove the dependency of ObjectOne to be an argument inside class constructor, by giving the contract from ObjectOne (ObjectOne should be abstract class/interface, that being inheritance or implemented by implementedObject).

before we read about the third Injection way, you could see how it’s implemented in Spring by using this link. Continue to the third Injection, it’s the interface injection, this is the example of Interface Injection:

3. Interface Injection

** Interface Injection
```
public interface ObjectContract {
setAbstractObject(ObjectOne implementedObject);
...
}
public class Message implement ObjectContract {
private ObjectOne abstractObject;
public Message(){
}
@override
public void setAbstractObject(ObjectOne implementedObject){
this.abstractObject = implementedObject;
}
...
}

With this way, we make sure that we have to implement the contract of the injection in Message class, so we must have setter(s) as we define in ObjectContract, it will help you to define the contract of the Injection for that blueprint of the object. Continue to another Example is about Field Injection, field injection is an injection way that automatically provided when you use Spring by using @autowired annotation.

4. Field Injection

** Field Injection

import com.package.ObjectOne;
public class Message {
@autowired
private ObjectOne abstractObject;
public Message(){
}
public void setAbstractObject(ObjectOne implementedObject){
this.abstractObject = implementedObject;
}
...
}

by using annotation injection, you don’t need to configure more about the object, because the annotation injection using Runtime Injection or we can called it as using Metaprogramming.
you can learn about annotation injection from this links :

https://www.baeldung.com/constructor-injection-in-spring
https://dzone.com/articles/dependency-injection-an-introd
https://www.journaldev.com/2623/spring-autowired-annotation
https://dzone.com/articles/about-dependency-injection
https://www.baeldung.com/spring-annotations-resource-inject-autowire
https://dzone.com/articles/ioc-vs-di

Example of Framework that use Dependency Injection

Spring

One example of framework that use DI is Spring, they have their way to do Dependency Injection, they do it by doing annotation Injection that using Runtime Injection, they use Reflection or we can say that Reflection is one of Metaprogramming (they define the object at runtime, use it at runtime, and change it at runtime).

Dagger 2

Another framework is Dagger in Android (Right now is dagger 2). Dagger 2 use Compile Time Injection, which is use Template Metaprogramming (So they will define the object at compile time).

Spring vs Dagger 2

Why do dagger 2 use Compile Time Injection rather than Runtime Injection like Spring does? in the matter of Performance, so Android as a limited resource, will define the object at compile time and just use it in at runtime.
but what is Metaprogramming? Metaprogramming is a way to threat our code as a Data, and modify it at runtime.

Java Specificatin Request (JSR)
So, what should we know about Depenjency Injection in Java is about the JSR. JSR is like IEEE, but focus on Java, means like it’s the change request to make Java and it’s library better and better. This Dependency Injection specify in JSR 330. What they said about the change request is, they propose to maximize reusability, testability and maintainability of Java code by standardizing an extensible dependency injection API.

--

--