Overview
Whenever we want to use one class features (let say java class name as Bank) into another class (let say java class name as Shop), we have to use below approach.
Here Shop java class have dependency on Bank java class that is to perform any bank related operation by Shop, it first need to create the object of Bank and then use. So, we can say Shop is tightly coupled with Bank. Tight coupling is usually considered as bad practice.
Now, questions comes that "Why tight coupling is bad?"
- Tight
coupling makes the future enhancement or changes more difficult.
for
e.g. if in future, shop want to change its bank like currently shop using bank A but want to
change it to bank B. then it will become very difficult to implement these changes at code
level.
- Unit testing on tightly coupled applications requires more efforts and time as compare to loosely coupled applications. Also, in tightly coupled, we have less or no options of mocking the dependency.
Now, to overcome from this situation we have to make objects or beans loosely coupled and here dependency Injection comes into play.
Dependency Injection : It is a design pattern that helps in achieving lose coupling by moving the responsibility of managing Beans to Spring Boot container (IOC container or Inversion of Control container).
Now, IOC container in spring boot is use to perform following operations throughout the lifecycle of a bean (Object) :
→ To create beans(objects)
→ Hold beans(objects) in memory
→ Inject them in other beans whenever require.
Now, IOC and DI introduces in Core Spring framework, Spring boot is built on top of Spring. So, it uses all these concept. But we don't have to configure IOC container in spring boot as we usually do in spring using config.xml file. Now in Spring Boot, it is auto configurable for us.
The overall goal of DI(Dependency Injection) is to achieve loose coupling. One more important point to note that, to decouple beans/objects, we uses interface because interface defines the contract but it doesn't expect an implementation making it easier to switch between different implementations of that interface.
Let see, how we can directly use DI in spring boot. Before that we need to have a look on different ways to inject dependencies.
- Property or Field injection
- Method Injection or Setter injection
- Constructor Injection
Also, before moving to each and every way, we first need to understand some annotations that we mainly use in spring boot for DI.
1. @Autowired : It uses as shown in below code snippet.
→ It specify that Bank bean needs to be injected in Shop bean.
2. @Component : it is use to register custom classes as beans to the IOC container and such classes will be automatically detect by Spring using classpath scan.
→ @Service, @Repository, and @Controller are specializations of @Component, which are used for more specific cases.
→ Like @Service use to specify a bean for service layer,
→ @Repository for DAO layer,
→ @Controller is used to specify a bean at presentation layer. That is whenever any request comes from client or user, that request is handle by that bean having annotation @Controller.
3.
@Qualifier :
It is use to resolve the ambiguity when we have multiple implementation of the single
interface.
Now, let go back to different ways to inject dependencies,
(i) Property or Field Injection :
- In this type, We creates a variable/field/property (let say bankService in our case) of the class (let say BankService) that we want to inject in our class (ShopController) and Also, annotate that variable/field/property (i.e. bankService) with @Autowired annotation. so, that when our class (ShopController) will instantiae then IOC container will inject this dependency (i.e. BankService) for us.
- Most
of the developer when learns DI, they use it during the beginning of their learning because
of short,clear and
concise code.But it
is not considered as good practice
to use it.
(ii) Method Injection or Setter Injection :
- In
this, we have to create setter method that is annotated
with @Autowired.
(iii) Constructor Injection :
- It is widely used among developers and considered as good practice to have it in your code.
- In this, we have to create the class constructor in which we have to pass the arguments which refer to dependencies that spring IOC container will inject for us.
- If
we only passing one argument in the constructor then it is not
mandatory to
use @Autowired annotation
otherwise we have to use it.
Note
: Please comment below for any improvement , suggestions, regarding any wrong information
present in this article. We will improve it so that only right information available in this
article.