Learning Dependency Injection the Series: Part 1 — Dependency Injection in Spring Framework
When I’m a part of the DANApprentech program, there was an interesting training program on the technical skills. I’m sure some of you have heard about the Spring Frameworks and Dependency Injection. For this first article, I want to share my experiences learning about Dependency Injection during the training program and also from other sources related to Spring Dependency Injection.
This article will consist of several parts. In the first part I will cover about “Understanding Dependency Injection in the Spring Framework”. It has general explanation about Dependency Injection, the concept of Tight and Loose Coupling and the differences, and more detail of the Dependency Injection concept. Every material of this article is connected, please make sure you read sequentially so you gain more benefit from this article.
~ “Enjoy Your Reading 😊“
1. Dependency Injection Overview
According to a document entitled “Spring Framework Reference Documentation” written by Rod Johnson, it is explained that:
“IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern.“
For more details, please visit the following link.
Dependency Injection, also known as Inversion of Control, is one of the special features of the Spring Framework. Before starting to use or learning the Spring Framework, it is better to understand the concept of Dependency Injection correctly, because it is a key element of the Spring Framework.
In the Spring Framework, the Dependency Injection is used by the Spring containers to manage the components that make up an application (an illustration of a Spring container can be seen in figure 1). The Spring container is at the core of the Spring Framework. They are responsible for instantiating, configuring, and assembling the beans. Take a look again at figure 1 with the symbol A, there can be seen a Java Object or POJO, POJO is an ordinary Java class, where it stands alone and does not depend on other classes. On the symbol B, there is a “configuration metadata”, which is used to tell the Spring container to instantiate, configure, and assemble objects in the application.
At first, the Spring container (see figure 1 symbol C) gets an instruction about which Java Object will be instantiated, configured, and created its bean by reading the configuration metadata that has been created, it can be created using the .xml file, annotation (@) or java code. After the configuration process is finished, a bean will be made as shown in figure 1 symbol D.
In general, a Java application is built from a collection of several beans. A good bean is one that has Loose Coupling characteristics. In this case, it means reducing dependency between beans. The opposite of it is Tight Coupling, which means that it has a tight dependence between beans.
Previously there was a statement, “.. java application is built from a collection of several beans”. Now the question is, what are beans?. The objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. For a more detailed explanation about beans, please visit the following link.
2. Coupling
Coupling measures how enormous each bean is depending on other beans. figure 2 below shows the Tight Coupling (symbol A) and Loose Coupling (symbol B) illustrations.
A. Tight Coupling
It is assumed that the circles above are a class or an object or a bean so that between classes, objects or beans has a dependence on each other as shown in figure 2A. Therefore, Tight Coupling occurs when a group of classes or objects or beans are highly dependent on one another. To get a clear picture, look at the following code snippet:
Ok, let’s play around with the code. In the code above, the Dana class depends on the DanaBoarding class, if there are changes in the DanaBoarding class, it will also affect the Dana class. A very tight couple isn’t it.
The explanation is as follows:
The object first is an instantiation of the DanaBoarding class which is declared in the Dana class. There is a void welcome() method, which contains the sentence “WELCOME TO A START” in the DanaBoarding class. When the welcome() method is called by the object first in the Dana class and the main method is executed. It will produce the sentence “WELCOME TO A START”. At this point, there may not be any problems arise yet and the program is running well. A problem may arise when there are other objects created from the DanaBoarding class and the welcome() method but they have different values. For more details, take a look at code 2.
In this code, it is obvious that the Dana class is very dependent on the DanaBoarding class. Changes in the value of the welcome() method that is done by the object second, making the value of the object first is also changed.
B. Loose Coupling
It is the opposite of the concept from previously discussed. Loose Coupling concept can reduce the dependency between classes or objects or beans. How can we do that concept? How to change the code from tight into a loose coupling one? Please follow the steps below:
Create an interface — An interface supports the implementation of Loose Coupling because there is no business logic in it. The examples can be seen in code 3.
Implementing the interface — The next step is to implement the interface that has been made in code 3. The business logic that wants to be created on each bean is created in this process. As shown in Code 4. The first and second classes both have a welcome() method but have different values.
Creating an Object From the Implementation Class — The DanaBoarding is an interface created in code 3, while the First() and Second() are derived from classes that implement the DanaBoarding interface. If the main class is executed, then we will obtain different values.
3. The Concept of Dependency Injection
After fully understand the Loose Coupling concept, then we can understand the concept of Dependency Injection easier. The development of the Dependency Injection program is not much different from the procedures for making the Loose Coupling program above, the difference is in the last process, that is in the discussion of “Creating an Object From an Implementation Class”, in Dependency Injection this process will be managed by a Spring container, by performing a configuration metadata.
As previously explained, configuration metadata can be represented by XML, Java Annotation (@), or Java code. To understand the concept of Dependency Injection more easily, I used the .xml file to configure the beans. The configuration process itself can be done in two ways, which are through the setter method and the constructor.
To shorten this article, let’s assume that we have made the program up to code 5, then it is changed into code 6.
In code 6, the code used to perform the Dependency Injection process is shown. To make it simple, I divided it into several steps:
Declaring the interface that has been made (in this case as in code 3) and it has been implemented (as in code 4). To do an injection, we can use the Setter method or the Constructor depending on our needs, to make it simple let’s just use the Setter method to do the injection process. And then, configure the XML file, such as in code 7. The following explanation is based on the number in code 7.
The bean is used to mark which objects will be managed by the Spring container. The id is a string used to identify bean definitions individually. The class is used to define the location of the object that will call. The name refers to the JavaBean property name. The ref is a reference from other beans.
After the injection is performed, then the DanaBoarding variable already has a usable value.
This injection process explains the term “Dependency Injection”. By using the Dependency Injection features, all of the beans will be Loose Coupling. If there is a change in one of them, then the changes need only be made in the configuration file. That is why Dependency Injection is necessary, and why its features are so important to be learned at the beginning of learning the Spring Framework. That is the article from me for now, hopefully, it will be useful, please wait for my next article. Thanks….😊