Inversion of Control(IoC) in Spring

What is Inversion of Control?

Inversion of Control is a principle in software engineering by which the control of objects or portions of a program is transferred to a container or framework. It’s most often used in the context of object-oriented programming.

The advantages of this architecture are:

  • decoupling the execution of a task from its implementation
  • making it easier to switch between different implementations
  • greater modularity of a program
  • greater ease in testing a program by isolating a component or mocking its dependencies and allowing components to communicate through contracts

Inversion of Control can be achieved through various mechanisms such as: Strategy design pattern, Service Locator pattern, Factory pattern, and Dependency Injection (DI).

What is Dependency Injection?

Dependency injection is a pattern through which to implement IoC, where the control being inverted is the setting of object’s dependencies.

The act of connecting objects with other objects, or “injecting” objects into other objects, is done by an assembler rather than by the objects themselves.

In Spring Framework, the Inversion of Control (IoC) principle is implemented using the Dependency Injection (DI) design pattern.

Dependency Injection in Spring can be done through constructors, setters or fields.

Constructor-Based Dependency Injection

Construct-injection.jpg

Person.java

package com.spring.example.bean;

public class Person {

private Address address;

public Person(Address address) {
this.address = address;
}

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

}

Address.java

package com.spring.example.bean;

public class Address {

private String city;

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

}

TestBeanLifeCycle.java

package com.spring.example.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spring.example.bean.Person;

public class TestBeanLifeCycle {

public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
“beanConfig.xml”);
Person person = (Person) context.getBean(“person”);
System.out.println(person.getAddress().getCity());
context.close();

}
}

Output
Mumbai

Setter-Based Dependency Injection

setter-injection

Person.java

package com.spring.example.bean;

public class Person {

private Address address;

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

}

Address.java

package com.spring.example.bean;

public class Address {

private String city;

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

}

TestBeanLifeCycle.java

package com.spring.example.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spring.example.bean.Person;

public class TestBeanLifeCycle {

public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
“beanConfig.xml”);
Person person = (Person) context.getBean(“person”);
System.out.println(person.getAddress().getCity());
context.close();

}
}

Output
Mumbai

Field-Based Dependency Injection using @Autowired

field-injection.jpg

Person.java

package com.spring.example.bean;

public class Person {

@Autowired
private Address address;

public Address getAddress() {
return address;
}

}

Address.java

package com.spring.example.bean;

public class Address {

private String city;

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

}

TestBeanLifeCycle.java

package com.spring.example.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spring.example.bean.Person;

public class TestBeanLifeCycle {

public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
“beanConfig.xml”);
Person person = (Person) context.getBean(“person”);
System.out.println(person.getAddress().getCity());
context.close();

}
}

Output
Mumbai

Using Java Based Configuration(No Xml stuff :))

Person.java 

package com.spring.example.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Person {

@Autowired
private Address address;

public Address getAddress() {
return address;
}

}

       Address.java

package com.spring.example.bean;

public class Address {

private String city;

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

}

BeanConfiguration.java

package com.spring.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import com.spring.example.bean.Address;

@ComponentScan(basePackages = “com.spring.example.bean”)
@Configuration
public class BeanConfiguration {

@Bean
public Address address() {
Address address = new Address();
address.setCity(“Mumbai”);
return address;
}

}

TestBeanLifeCycle.java

package com.spring.example.test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.spring.example.bean.Person;
import com.spring.example.config.BeanConfiguration;

public class TestBeanLifeCycle {

public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(BeanConfiguration.class);
Person person = context.getBean(Person.class);
System.out.println(person.getAddress().getCity());
context.close();
}

}

Output
Mumbai

Leave a Reply

Your email address will not be published. Required fields are marked *