Spring Core | Dependency Injection

In the previous post, we understood what is spring framework all about. We saw what the spring framework has to offer while building a java application. We went through different modules in brief and understood their functionalities. In this section, we will go through the spring core in detail. If you haven’t checked it out yet, I highly recommend you to go through it. What is the Spring Framework?

When I started learning spring, to be honest it was scary at first instance to see a lot of XMLs and annotations used in applications. But slowly and steadily, everything started making sense and I could realize how it empowers POJOs and I don’t even have to worry about injecting dependencies into an object. Spring takes care of instantiating objects and injecting wherever it requires. Yes, we will be understanding Dependency Injection!

Dependency Injection

As I mentioned earlier, the term dependency injection (DI) or Inversion of Control (IOC) might be sounding intimidating at first. But we will see how by applying DI in our project, we’ll find that our code becomes simpler, easier to understand and significantly easier to test.

Any non-trivial java application would comprise more than one class that collaborate with each other to perform some business logic. Traditionally, each object is responsible for obtaining a reference of another object with which it collaborates (its dependency). For example:

package com.lifeinhurry.person;
public class Student implements Person{
    private Subject history;
    public Student(){
       this.history = new Subject();
    }
    public void attendSubject(){
       history.attend();
    }
}

In the above example, you see Student creates its own Subject history, in the constructor. This couples history subject tightly into the Student class. What if a teacher asks Student to attend literature. Student class doesn’t have any way to do that.

dependency-injection
Dependency Injection

With Dependency Injection, objects are given their dependency at the creation time by some third-party system. Object isn’t expected to create or obtain their own dependencies. To illustrate this point let’s look into another example, a Student class who is capable of attending any subject.

package com.lifeinhurry.person;
public class Student implements Person{
    private Subject subject;
    public Student(Subject subject){
       this.subject = subject;
    }
    public void attendSubject(){
       subject.attend();
    }
}

As you can see Student class is given a subject at construction time as a constructor argument. This type of DI is called constructor injection.

If you see the above example carefully, the Student class is not coupled to any subject tightly. It doesn’t matter what type of subject he is asked to attend, as long as it implements Subject Interface. That’s the power of Dependency Injection – loose coupling.

One of the key benefits of loose coupling is a mock implementation during testing. You can easily test Student class by giving it a mock implementation of Subject, as shown below:

package com.com.lifeinhurry.person;
import static org.mockito.Mockito.*;
import org.junit.Test;
public class StudentTest{
    @Test
    public void testAttendSubject() {
         Subject mockSubject = mock(Subject.class);
         Student student = new Student(mockSubject);
         student.attendSubject();
         verify(mockSubject, times(1)).attend();
    }
}

We created a mock object of Subject Interface using a framework Mockito, with this mock object in hand we create an instance of Student, injecting a mock Subject via the constructor. After calling the attendSubject() method, we ask Mockito to verify that the mock Subject’s attend() method was called only once.

Conclusion

In this post, we learned how with the help of dependency injection, we can create a loosely coupled system. Loose coupling also ensures each component can be tested thoroughly. However, the big question here is how can you give a Subject object to a Student class? The act of creating this association is called wiring which we will learn in our next post.