What is IoC (Inversion of Control)
IoC is a process to define the dependency on Other Object(Objects they will work with). In the normal scenario, we first inject the dependency and then create the bean(Using New keyword) but in this case, we will first create the bean and then inject the dependencies hence it is called Inversion of Control(IoC).
Responsibility of IoC
- Instantiating Bean
- Assembling Bean
- Managing Bean
Advantage of Using IoC
- Loosely coupled architecture
- Configuration and Code is separate
- Making components free from managing their dependencies
- A mechanism to share resources throughout the application.
- Easy to test code
- No App server dependencies
Components Involved in IoC
- BeanFactory (org.springframework.beans)
- ApplicationContext (org.springframework.context)
BeanFactory
It provides configuration framework and basic functionality.
ApplicationContext(AC)
It is a subinterface of the BeanFactory, It has all the feature which Beanfactory provides with some extra enterprise-specific functionality like Integration with AOP feature, Message Resource Handling, Event Publication and easier integration with WebApplicationContext.
How it Works
- Step 1: Business Object is defined
- Step 2: Configuration Metadata is defined for the given object
- Step 3: Spring Container reads the Metadata
- Step 4: Container inject required dependencies in Object (As defined in Metadata)
- Step 5: Prepare Bean
Type of Metadata Definition
There are 3 ways configuration metadata can be defined.
1- XML(Traditional way)
- Setter Dependency Injection(No-Arg Constructor) Example
- Setter Dependency Injection(No Arg Factory) Example
- Constructor Dependency Injection Example
2- Java Config
3- Annotations (Spring 2.5 Introduced)
Note*: XML injection is done after Annotation injection, hence if properties are wired via both approaches then XML approach will take precedence.
Example of IoC
Step 1: Define a business object
Company.java
package jbt.bean;
public class Company {
public String bldgNo;
public String streetNo;
public String city;
public String getStreetNo() {
return streetNo;
}
public void setStreetNo(String streetNo) {
this.streetNo = streetNo;
}
public String getBldgNo() {
return bldgNo;
}
public void setBldgNo(String bldgNo) {
this.bldgNo = bldgNo;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address [flatNo=" + ", bldgNo=" + bldgNo + ", streetNo="
+ streetNo + ", city=" + city + ", pincode=" + "]";
}
}
Step 2 : Define Configuration Metadata(XML) for above object
ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- Here we are using setter injection for DI -->
<bean id="address" class="jbt.bean.Company" name="company1">
<property name="bldgNo">
<value>2C</value>
</property>
<property name="streetNo">
<value>JBT Street</value>
</property>
<property name="city">
<value>New York</value>
</property>
</bean>
</beans>
Step 3: Spring Container Reads the metadata
ApplicationContext cpxac = new ClassPathXmlApplicationContext(
"ApplicationContext.xml");
Step 4: Spring container inject the dependencies
Here container will use Setter Injection to inject the dependencies.
Step 5: Prepare bean
Company company1 = (Company) cpxac.getBean("company1");