In this tip we will look at what Dependency Injection is and how this design pattern can be helpful.
While working on different projects we sometimes come across situations where Java components are tightly coupled. In such cases the component looses its reusability. Using Dependency Injection(DI) we can decouple the components and increase the chance of reusability also independent components can easily be tested (unit testing).
Example:
Let us take a simple example to get more clarification on this pattern.
We have one interface, Bank ,that has one method – getNumberOfBranches()
public interface Bank { public String getNumberOfBranches(); }
There are two classes IciciBank and the AxisBank both implement Bank interface and override getNumberOfBranches() method.
public class IciciBank implements Bank { //Override public String getNumberOfBranches() { return "ICICI has got 144 branches all over India"; } } public class AxisBank implements Bank { //Override public String getNumberOfBranches() { return "Axis has got 111 branches all over India"; } } The service class prints the result . public class MyBankService { private Bank bank = new IciciBank(); public void getBankResult() { System.out.println(bank.getNumberOfBranches()); } } Main method to get the number of branches.Here we create an instance of the service class and calls the getBankresult() method. public class BankData { public static void main(String[] args) { MyService myService = new MyService(); myService.getBankResult(); } }
When we execute this main method it will, as is obvious, print “ICICI has got 144 branches all over India” as the Bank object refers to IciciBank class. Now if we want to display the count of Axis bank we need to change the code in MyBankService class. So here the classes are tightly coupled.
DI comes into picture:
Imagine if there is some way so that we don’t have to hard code Bank object (manually instantiate) in the MyBankservice class and this could be done automatically in the runtime. Then our problem is solved as the class MyBankService is now independent/loosely coupled from other classes.
To decouple components from other components the dependency to a certain class should be injected to them, so that the component do not need to worry about creating the class object and it is independent of other classes. This is what the DI design pattern is.
IoC container: In Spring we can take the help of Inversion of Control(IoC) container to inject the required dependencies into a class. IoC container does everything for us and we don’t have to worry about instantiating classes. As per our example we don’t need to create object of Bank class inside the MyBankService class but rather we can
fall upon the container to do this for us.
Dependencies can be injected in two different ways setter or constructor injection. We will look at how we can do this using setter injection .
Lets modify the MyBankService class and add a setter method to set the Bank object.
public class MyBankService { private Bank bank; //Setter for Bank public void setBank(Bank bank) { this.bank = bank; } public void getBankResult() { System.out.println(bank.getNumberOfBranches()); } }
Now the value of Bank is set using the setBank method so here we are not instantiating the Bank class anymore but the class will be instantiated automatically by the IoC container.
To make the container aware of the dependent class and the dependencies we can set up the configuration file like this :
Here “id” attribute gives a logical name to the class and the “class” attribute represent the actual class. The “property” tag refers to the property of the bean class and “ref” tag is used to inject the bean class.
This is all there is, about DI design pattern and how easily we can use this design pattern with the help of IoC container in Spring framework.