Dependency Injection.
This concept of dependency injection has a lot of popularity in Java lately thanks to Spring Framework. It is also a fundamental part of the modules that compose Spring Framework Core Container and I will explain how it works.
Definition
It is a process in which objects define their dependencies, this refers to the instances of the other objects with which they work. This can be accomplished in the following three ways:
- Receive the instance as the constructor’s parameter or argument
- Also as a parameter or argument towards a factory method.
- Or as a property that is instantiated after the class is built.
The Spring Framework container injects these dependencies when the Bean is created. This process is inverse, which links it to the concept inversion of Control or better known as the IoC,
The code is much cleaner and uncoupled with the principle of injection of dependencies. It is much more effective when the objects are delivered by their dependencies.
As we saw in the previous tutorial (Spring boot Profiles Part 2) No matter what the operating system the code works in the same way. The object does not have to look for the dependencies or instances of the objects it works with or its location.
You can read more about this in the official Spring documentation and you can look for a bit about polymorphism in Java.
Https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/beans.html
Https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/beans.html#beans-factory-collaborators
Test scenario
We made a Stand Alone application with Spring Boot that uses the terminal or command unit of the operating system, for it needs to know the syntax and some characteristics of each one.
We have an interface of a service that is called operating system, this service will return some unique values for each operating system, as it is the name, the extension of libraries of the OS and the extension of the executable files.
Execution
This would be the result.
Dependency Injection
by constructor
This method is the most recommended, because it would give you the necessary visibility of how many injections your class has and is easier to debug.
@Controller public class DemoController { SistemaOperativoService sistemaOperativoService; @Autowired//Anotacion Optional from version 4.3 Public DemoController (SistemaOperativoService sistemaOperativoService) { this. SistemaOperativoService = sistemaOperativoService; } }
Factory or Setter method
It is mostly used for optional injections.
@Controller public class DemoController { SistemaOperativoService sistemaOperativoService; Public DemoController () { } @Autowired public void SetSistemaOperativoService (sistemaOperativoService SistemaOperativoService) { this.sistemaOperativoService = sistemaOperativoService; } }
Direct ownership
Very fast and effective with very small classes.
@Controller public class DemoController { @Autowired SistemaOperativoService sistemaOperativoService; }
STOP: Nothing described above serves you when you have multiple implementations of an interface. You have to specify the desired Bean to inject.
There are also 3 ways to define it.
- @Primary: You can note an implementation as “primary” to indicate that in case of confusion inject this Bean:
-
@Service @Primary public class SistemaOperativoServiceWindows Implements SistemaOperativoService { //Interface methods }
-
- @Qualifier: By means of a String (started with lowercase) it explicitly indicates that Bean should be injected:
-
@Controller public class DemoController { SistemaOperativoService SistemaOperativoService; Public DemoController(@Qualifier("sistemaOperativoServiceLinux") SistemaOperativoService sistemaOperativoService) { this. SistemaOperativoService = sistemaOperativoService } }
-
- Naming: The name of the parameter the constructor receives must have the name of the Bean you want to inject. ALERT If there is a class with annotation @Primary this will have greater weight and ignore the naming of the variable:
-
@Controller public class DemoController { SistemaOperativoService sistemaOperativoService; Public DemoController (SistemaOperativoService sistemaOperativoServiceLinux) { this.sistemaOperativoService = sistemaOperativoServiceLinux; } }
-
BONUS
Watch my video on YouTube where I explain more and you can see me coding these examples.
Thanks for coming to the end of this post, do not forget to leave your comments.