- Spring DI - Discussion
- Spring DI - Useful Resources
- Spring DI - Quick Guide
- Spring DI - Non-Static Factory
- Spring DI - Static Factory
- Spring DI - Autowiring Constructor
- Spring DI - Autowiring ByType
- Spring DI - Autowiring ByName
- Spring DI - Autowiring
- Spring DI - Map Ref Setter
- Spring DI - Map Setter
- Spring DI - Collection Ref Setter
- Spring DI - Collections Setter
- Spring DI - Inner Beans Setter
- Spring DI - Setter Based
- Spring DI - Map Ref Constructor
- Spring DI - Map Constructor
- Spring DI - Collection Ref Constructor
- Spring DI - Collections Constructor
- Spring DI - Inner Beans Constructor
- Spring DI - Constructor Based
- Spring DI - Create Project
- Spring Dependency Injection
- Spring DI - IOC Containers
- Spring DI - Environment Setup
- Spring DI - Overview
- Spring DI - Home
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Spring Dependency Injection
Every Java-based apppcation has a few objects that work together to present what the end-user sees as a working apppcation. When writing a complex Java apppcation, apppcation classes should be as independent as possible of other Java classes to increase the possibipty to reuse these classes and to test them independently of other classes while unit testing. Dependency Injection (or sometime called wiring) helps in gluing these classes together and at the same time keeping them independent.
Consider you have an apppcation which has a text editor component and you want to provide a spell check. Your standard code would look something pke this −
pubpc class TextEditor { private SpellChecker spellChecker; pubpc TextEditor() { spellChecker = new SpellChecker(); } }
What we ve done here is, create a dependency between the TextEditor and the SpellChecker. In an inversion of control scenario, we would instead do something pke this −
pubpc class TextEditor { private SpellChecker spellChecker; pubpc TextEditor(SpellChecker spellChecker) { this.spellChecker = spellChecker; } }
Here, the TextEditor should not worry about SpellChecker implementation. The SpellChecker will be implemented independently and will be provided to the TextEditor at the time of TextEditor instantiation. This entire procedure is controlled by the Spring Framework.
Here, we have removed total control from the TextEditor and kept it somewhere else (i.e. XML configuration file) and the dependency (i.e. class SpellChecker) is being injected into the class TextEditor through a Class Constructor. Thus the flow of control has been "inverted" by Dependency Injection (DI) because you have effectively delegated dependances to some external system.
The second method of injecting dependency is through Setter Methods of the TextEditor class where we will create a SpellChecker instance. This instance will be used to call setter methods to initiapze TextEditor s properties.
Thus, DI exists in two major variants and the following two sub-chapters will cover both of them with examples −
Sr.No. | Dependency Injection Type & Description |
---|---|
1 |
Constructor-based DI is accomppshed when the container invokes a class constructor with a number of arguments, each representing a dependency on the other class. |
2 |
Setter-based DI is accomppshed by the container calpng setter methods on your beans after invoking a no-argument constructor or no-argument static factory method to instantiate your bean. |
You can mix both, Constructor-based and Setter-based DI but it is a good rule of thumb to use constructor arguments for mandatory dependencies and setters for optional dependencies.
The code is cleaner with the DI principle and decouppng is more effective when objects are provided with their dependencies. The object does not look up its dependencies and does not know the location or class of the dependencies, rather everything is taken care by the Spring Framework.
Constructor Based V/s Setter Based Dependency Injection.
There are few noteworthy differences between constructor based and setter based dependency injection.
Granular control − In case of a constructor accepting multiple values, we need to pass all the values during bean configuration while in case of setters, we can pass value in a particular setter method and can leave other setter unconfigured.
Setter Overrides Constructor − In case of both constructor and setter based injection are used then setter based injection takes preference.
Flexibipty − Setter methods doesn t create a new bean instance pke constructor and their values can be changed as well.