For example: Suppose we have an object Employee
and it has a dependency on object Address
. We would define a bean corresponding to Employee
that will define its dependency on object Address
.
When Spring tries to create an Employee
object, it will see that Employee
has a dependency on Address
, so it will first create the Address
object (dependent object) and then inject it into the Employee
object.
Inversion of Control (IoC) and Dependency Injection (DI) are used interchangeably. IoC is achieved through DI. DI is the process of providing the dependencies and IoC is the end result of DI. (Note: DI is not the only way to achieve IoC. There are other ways as well.)
By DI, the responsibility of creating objects is shifted from our application code to the Spring container; this phenomenon is called IoC.
I shall write down my simple understanding of this two terms: (For quick understanding just read examples)
Dependency Injection(DI):
Dependency injection generally means passing a dependent object as a parameter to a method, rather than having the method create the dependent object.
What it means in practice is that the method does not have a direct dependency on a particular implementation; any implementation that meets the requirements can be passed as a parameter.
With this implementation of objects defines their dependencies. And spring makes it available.
This leads to loosely coupled application development.
Quick Example:EMPLOYEE OBJECT WHEN CREATED,IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT (if address is defines as dependency by Employee object)*.
Inversion of Control(IoC) Container:
This is common characteristic of frameworks, IoC manages java objects
- from instantiation to destruction through its BeanFactory.
- Java components that are instantiated by the IoC container are called beans, and the IoC container manages a bean's scope, lifecycle events, and any AOP features for which it has been configured and coded.QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it
.
By implementing Inversion of Control, a software/object consumer get more controls/options over the software/objects, instead of being controlled or having less options.
Inversion of control as a design guideline serves the following purposes:
- There is a decoupling of the execution of a certain task from implementation.
- Every module can focus on what it is designed for.
- Modules make no assumptions about what other systems do but rely on their contracts.
- Replacing modules has no side effect on other modules
I will keep things abstract here, you can visit following links for detail understanding of the topic.
A good read with example
Detailed explanation
In Spring Objects are loosely coupled i.e., each class is independent of each other so that everything can be tested individually. But when using those classes, a class may be dependent on other classes which need to be instantiated first.
So, we tell spring that class A is dependent on class B. So, when creating bean(like class) for class A, it instantiates class B prior to that of class A and injects that in class A using setter or constructor DI methods. I.e., we are telling spring the dependency at run-time. This is DI.
As, we are assigning the responsibility of creating objects(beans), maintaining them and their aggregations to Spring instead of hard-coding it, we call it Inversion Of Control(IOC).
Inversion Of Control (IOC):
IoC is a design pattern that describes inverting the flow of control in a system, so execution flow is not controlled by a central piece of code. This means that components should only depend on abstractions of other components and are not be responsible for handling the creation of dependent objects. Instead, object instances are supplied at runtime by an IoC container through Dependency Injection (DI).
IoC enables better software design that facilitates reuse, loose coupling, and easy testing of software components.
Dependency Injection (DI):
DI is a technique for passing dependencies into an object’s constructor. If the object has been loaded from the container, then its dependencies will be automatically supplied by the container. This allows you to consume a dependency without having to manually create an instance. This reduces coupling and gives you greater control over the lifetime of object instances.
click to view more
Inversion of control- It means giving the control of creating and instantiating the spring beans to the Spring IOC container and the only work the developer does is configuring the beans in the spring xml file.
Dependency injection-
Consider a class Employee
class Employee {
private int id;
private String name;
private Address address;
Employee() {
id = 10;
name="name";
address = new Address();
}
}
and consider class Address
class Address {
private String street;
private String city;
Address() {
street="test";
city="test1";
}
}
In the above code the address class values will be set only when the Employee class is instantiated, which is dependency of Address class on Employee class. And spring solves this problem using Dependency Injection concept by providing two ways to inject this dependency.
Setter method in Employee class which takes a reference of Address class
public void setAddress(Address addr) {
this.address = addr;
}
Constructor in Employee class which accepts Address
Employee(Address addr) {
this.address = addr;
}
In this way the Address class values can be set independently using either setter/constructor injection.
Spring: Spring is “Inversion of Control” container for the Java Platform.
Inversion of Control (IoC): Inversion of Control (IoC) is an object-oriented programing practice whereby the object coupling is bounded at runtime by an "assembler" object and are typically not knowable at compile time using static analysis.
Dependency Injection (DI): "Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it possible to change them, whether at run-time or compile-time." -wiki.
Inversion of Control is a generic design principle of software architecture that assists in creating reusable, modular software frameworks that are easy to maintain.
It is a design principle in which the Flow of Control is "received" from the generic-written library or reusable code.
To understand it better, lets see how we used to code in our earlier days of coding. In procedural/traditional languages, the business logic generally controls the flow of the application and "Calls" the generic or reusable code/functions. For example, in a simple Console application, my flow of control is controlled by my program's instructions, that may include the calls to some general reusable functions.
print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);
//More print and scan statements
<Do Something Interesting>
//Call a Library function to find the age (common code)
print Age
In Contrast, with IoC, the Frameworks are the reusable code that "Calls" the business logic.
For example, in a windows based system, a framework will already be available to create UI elements like buttons, menus, windows and dialog boxes. When I write the business logic of my application, it would be framework's events that will call my business logic code (when an event is fired) and NOT the opposite.
Although, the framework's code is not aware of my business logic, it will still know how to call my code. This is achieved using events/delegates, callbacks etc. Here the Control of flow is "Inverted".
So, instead of depending the flow of control on statically bound objects, the flow depends upon the overall object graph and the relations between different objects.
Dependency Injection is a design pattern that implements IoC principle for resolving dependencies of objects.
In simpler words, when you are trying to write code, you will be creating and using different classes. One class (Class A) may use other classes (Class B and/or D). So, Class B and D are dependencies of class A.
A simple analogy will be a class Car. A car might depend on other classes like Engine, Tyres and more.
Dependency Injection suggests that instead of the Dependent classes (Class Car here) creating its dependencies (Class Engine and class Tyre), class should be injected with the concrete instance of the dependency.
Lets understand with a more practical example. Consider that you are writing your own TextEditor. Among other things, you can have a spellchecker that provides the user with a facility to check the typos in his text. A simple implementation of such a code can be:
Class TextEditor
{
//Lot of rocket science to create the Editor goes here
EnglishSpellChecker objSpellCheck;
String text;
public void TextEditor()
{
objSpellCheck = new EnglishSpellChecker();
}
public ArrayList <typos> CheckSpellings()
{
//return Typos;
}
}
At first sight, all looks rosy. The user will write some text. The developer will capture the text and call the CheckSpellings function and will find a list of Typos that he will show to the User.
Everything seems to work great until one fine day when one user starts writing French in the Editor.
To provide the support for more languages, we need to have more SpellCheckers. Probably French, German, Spanish etc.
Here, we have created a tightly-coupled code with "English"SpellChecker being tightly coupled with our TextEditor class, which means our TextEditor class is dependent on the EnglishSpellChecker or in other words EnglishSpellCheker is the dependency for TextEditor. We need to remove this dependency. Further, Our Text Editor needs a way to hold the concrete reference of any Spell Checker based on developer's discretion at run time.
So, as we saw in the introduction of DI, it suggests that the class should be injected with its dependencies. So, it should be the calling code's responsibility to inject all the dependencies to the called class/code. So we can restructure our code as
interface ISpellChecker
{
Arraylist<typos> CheckSpelling(string Text);
}
Class EnglishSpellChecker : ISpellChecker
{
public override Arraylist<typos> CheckSpelling(string Text)
{
//All Magic goes here.
}
}
Class FrenchSpellChecker : ISpellChecker
{
public override Arraylist<typos> CheckSpelling(string Text)
{
//All Magic goes here.
}
}
In our example, the TextEditor class should receive the concrete instance of ISpellChecker type.
Now, the dependency can be injected in Constructor, a Public Property or a method.
Lets try to change our class using Constructor DI. The changed TextEditor class will look something like:
Class TextEditor
{
ISpellChecker objSpellChecker;
string Text;
public void TextEditor(ISpellChecker objSC)
{
objSpellChecker = objSC;
}
public ArrayList <typos> CheckSpellings()
{
return objSpellChecker.CheckSpelling();
}
}
So that the calling code, while creating the text editor can inject the appropriate SpellChecker Type to the instance of the TextEditor.
You can read the complete article here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With