Spring IoC - Inversion of Control. DI - Dependency Injection.
Spring IoC - Inversion of Control
IoC pattern is defined as "A software design pattern and set of associated programming techniques in which the flow of control of a system is inverted in comparison to the traditional interaction mode." which means instead of the application calling the framework for services (as is the case with traditional patterns) it's the framework which calls the components as specified by the application.
DI - Dependency Injection
As you can deduce from the above para that IoC is quite generic in nature and perhaps not used by the Spring framework in entirety. The aspect of IoC used by the Spring framework is usually termed as DI or Dependency Injection as it focuses on injection of dependencies (required resources) into the dependent components at run time.
There are three main ways through which dependencies are injected into the dependent components. All these forms are supported in Spring either directly or indirectly. These forms are:
- Constructor Injection - as the name suggests, in this form the dependencies are injected using a constructor and hence the constructor needs to have all the dependencies (either scalar values or object references) declared into it. Though, this form of DI is directly supported by the Spring IoC Container. But, Constructor Injection is mainly used by a highly embeddable, lightweight, and full-service IoC Container named PicoContainer. Read more about how do we actually code Constructor Injection using Pico in this article - Implementing CI using Pico. How CI works?
- Setter/Mutator Injection - this form of DI uses the setter methods (also known as mutators) to inject the dependencies into the dependent components. Evidently all the dependent objects will have setter methods in their respective classes which would eventually be used by the Spring IoC container. This form of DI is also directly supported by Spring IoC Container. Though Spring framework supports both forms of DI namely the Constructor Injection and the Setter/Mutator Injection directly, but the IoC Container prefers the latter over the first.
- Interface Injection - in this case any implementation of the interface can be injected and hence it's relatively complex than the other two where the objects of specified classes are injected. It's not supported directly by the Spring IoC Container. Interface Injection is used by The Apache Avalon. In 2004 Apache Avalon project closed after growing into several sub-projects including Excalibur, Loom, Metro, and Castle.
Setter vs Constructor Injection. Why Spring prefers the former?
- Hard to manage a large number of constructor arguments: Spring framework prefers Setter/Mutator Injection over Constructor Injection because a large number of constructor arguments can become really hard to manage especially when many of them are optional. The Spring IoC Container will of course not have any such problem with Setter Injection type.
- Re-injection or Amendment: One important thing to note here is that in case of Constructor Injection the dependencies are handed over at the time of object instantiation of the dependent objects whereas in case of Setter/Mutator Injection the dependencies are injected after the dependent object has already been created. Now if a re-injection or re-configuration of a dependent object is required , it can be easily done by calling the respective Setters in case of Setter Injection, but not the same in case of the Constructor Injection. So, should you need any re-configuration of the dependent objects, you would be better off with Setter Injection.
Why at all do we have Constructor Injection then? Any real need?
Well... by saying that Spring IoC prefers Setter/Mutator Injection you should not deduce that the Constructor Injection has no real uses. Constructor Injection has its own benefit(s). This form of injection is preferred by the purists for the reason that the dependent objects are always handed over in a completely initialized state and no less than that. Right?
The obvious disadvantage in this case is that the dependent object becomes less flexible and hence any re-configuration becomes difficult.
How has the IoC pattern (or DI) been implemented in Spring framework?
Spring framework has two packages supporting this core functionality. These packages are: org.springframework.beans and org.springframework.context and the two interfaces which are the building blocks of Spring IoC are: BeanFactory and ApplicationContext.
ApplicationContext interface is actually a sub-interface of the BeanFactory interface. The top level interface, BeanFactory takes care of supporting an advanced configuration mechanism to manage objects of any type. ApplicationContext interface on the other hand is responsible for functionalities like integration to Spring AOP, message resource handling, event prorogation, and other enterprise-centric functionalities.
There are other specialized sub-interfaces as well which are targeted to add the specific set of functionalities on top of the the functionalities provided by ApplicationContext and BeanFactory interfaces. One such example is WebApplicationContext which is sub-interface of the ApplicationContext interafce and is responsible for providing enterprise-centric functionalities to be used in Web Applications.
Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.