What is dependency injection in Spring

Dependency injection is a design pattern that aims to take the responsibility of creating the instances of the classes that another object needs and supply it so that this class can use them.

What is dependency injection between classes?

Usually, our classes depend on other classes to work. For example, a class that needs to look up a record in the database will need another class to look it up. Let’s think about these two classes. Let’s call the first one CassA, which is in charge of making decisions about the business, and the second one ClassB, which will be in charge of accessing the database.

In dependency injection, an external ‘someone’ takes care of the dependencies that the classes need….

The ClassA depends on the ClassB to access the data in the database.

Spring Injection

Here in ClassA we would create ClassB .
The ClassA would be responsible for creating the ClassB.

Inversion of control in Spring

Spring handles the concept of IoC (Inversion of Control) taking care of keeping in its ‘context’ all the instances of our application and injecting that instance to whoever needs it.

Spring calls these instances beans .

The beans are the instances of the classes that are available for reuse and are managed within the Spring container.

IoC is the work Spring does by looking for these dependencies between objects and ‘setting’ these beans to whoever needs them.

Spring Injection

Spring knows what dependencies exist between instances and takes care of satisfying them.

It searches its beans container for the appropriate instance and adds it to the object, thus fulfilling the dependency injection.

Spring Injection

How we perform dependency injection with Spring

Spring gives us different ways to inject dependencies.

The most common and most recommended is by using annotations.

The general annotation to indicate that we want a class to be managed by the Spring container is @Component.

By annotating our class with @Component we tell Spring that we want that class to be a bean.

Therefore, Spring will do a new of the class and create the instance.

@Component
public class ClassB {
    public void doSomething() {
        System.out.println("working");
    }
}

Our class ClassA needs ClassB .

Spring realizes this dependency because our class is a component that in turn has in its constructor the ClassB .

Spring will create the ClassB and then when instantiating the ClassA it will pass this dependency to it in the constructor parameter.

@Component
public class ClassA {

    private final ClassB classB;

    public ClassA(ClassB classB) {
        this.classB = classB;
    }

    public void doSomething() {
        System.out.println("working");
        classB.doAnotherJob();
    }
}

What are the advantages of Dependency Injection?

Increased cohesion and reduced coupling:

Whenever we build an application we must think about reducing coupling between classes and increasing cohesion.

This means that each class should have a single responsibility, should be very specific in that responsibility, and do it well (cohesion).

By coupling reduction, we mean that changes in one class should not impact another.

By creating our classes knowing that Spring will be in charge of creating and injecting them, it frees us to focus only on the functionality of our class under construction.

We create our class and define its responsibilities thinking only about the scope of that class. We establish what the methods of that class will be so that they can be used by others, but without being aware of other classes.

Reuse:

A class is intended to be reusable by whoever needs it.

A class responsible for accessing the database can be used by others through the contract defined in its methods and be injected into all those that need access to the database.

Architectural changes:

Using interfaces allows us to make internal changes while maintaining the class contract, without affecting other classes that use it.

Tests:

Unit testing on classes is much simpler, and mocks can be used for classes outside the scope of the point test.

Conclusion

We understood the concept of dependency and IoC and how Spring helps us with the management of all dependencies between classes within our application. We saw that using Spring we can take care of creating our classes thinking only about their logic and leaving the task of dependencies in Spring. We understood the usefulness of IoC and its advantages.

See also