-
Spring Inversion of Control (IoC)Framework/SPRING 2020. 2. 6. 15:30
1. Overview
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. The container will create the objects, wire them together, configure them, and manage their complete life cycle from creation till destruction.
The responsibilities of IoC container are:
- Instantiating the bean
- Wiring the beans together
- Configuring the beans
- Managing the bean’s entire life-cycle
2. Description
2.1 Spring Container
The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. Spring framework provides two distinct types of containers.
2.1.1 BeanFactory container
BeanFactory is the root interface of the Spring IOC container. BeanFactory only instantiates bean when we call getBean() method
2.1.2 ApplicationContext container
2.2 Configuration Metadata
From the above diagram, the Spring IoC container consumes a form of configuration metadata. This configuration metadata represents how you, as an application developer, tell the Spring container to instantiate, configure, and assemble the objects in your application.
Three ways we can supply Configuration Metadata to Spring IoC container
- XML-based configuration
- Annotation-based configuration
- Java-based configuration
2.3 Create a Spring Container
2.3.1 AnnotationConfigApplicationContext
If we are using Spring in standalone Java applications and using annotations for Configuration, then we can use this to initialize the container and get the bean objects.
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
2.3.2 ClassPathXmlApplicationContext
If we have a spring bean configuration XML file in a standalone application, then we can use this class to load the file and get the container object.
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
2.3.3 FileSystemXmlApplicationContext
This is similar to ClassPathXmlApplicationContext except that the XML configuration file can be loaded from anywhere in the file system.
XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource("applicationContext.xml"));
2.4 Retrieve Bean from Spring Container
2.4.1 ApplicationContext getBean()
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
2.4.2 BeanFactory getBean()
XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource("beans.xml")); HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
3. DI and DL
3.1 Dependency Lookup (DL)
Lookup bean inside Bean Repository through API from container
3.2 Dependency Injection (DI)
Dependencies between classes are autowired based on Bean Definition. This approach is preferred than DL because it is less coupling.
3.2.1 Setter Injection
@Autowired public void setDao(DogsDao dao) { System.out.println("DogsService setter called"); this.dao = dao; }
public void setCity(String city) { this.city = city; }
<bean id="obj" class="com.javatpoint.Employee"> <property name="id"> <value>20</value> </property> <property name="name"> <value>Arun</value> </property> <property name="city"> <value>ghaziabad</value> </property> </bean>
3.2.2 Constructor Injection
@Component public class DogsService { private DogsDao dao; public List<Dog> getDogs() { System.out.println("DogsService.getDogs called"); return dao.getAllDogs(); } public void setDao(DogsDao dao) { System.out.println("DogsService setter called"); this.dao = dao; } public DogsService(){ System.out.println("DogsService no-arg constructor called"); } @Autowired public DogsService(DogsDao dao) { System.out.println("DogsService arg constructor called"); this.dao = dao; } }
3.2.3 Method Injection
public class Singleton { private Prototype prototype; public Singleton(Prototype prototype) { this.prototype = prototype; } public void doSomething() { prototype.foo(); } public void doSomethingElse() { prototype.bar(); } }
public abstract class Singleton { protected abstract Prototype createPrototype(); public void doSomething() { createPrototype().foo(); } public void doSomethingElse() { createPrototype().bar(); } }
As you noticed, code doesn't specify the createPrototype() implementation. This responsibility is delegated to Spring, hence the following needed configuration:
<bean id="prototype" class="ch.frankel.blog.Prototype" scope="prototype" /> <bean id="singleton" class="sample.MySingleton"> <lookup-method name="createPrototype" bean="prototype" /> </bean>
4. Reference
https://www.tutorialsteacher.com/ioc/introduction
https://www.youtube.com/watch?v=GKoCibDM6Ns&t=666s
https://www.baeldung.com/inversion-control-and-dependency-injection-in-spring
https://www.tutorialspoint.com/spring/spring_ioc_containers.htm
https://www.javaguides.net/2018/10/spring-ioc-container-overview.html
https://dzone.com/articles/method-injection-spring
https://www.amitph.com/spring-constructor-injection-example/
https://freecontent.manning.com/understanding-method-injection/
'Framework > SPRING' 카테고리의 다른 글
Portable Service Abstraction (PSA) (0) 2020.03.06 Dependency Injection (DI) (0) 2020.03.05 Spring Framework (0) 2020.02.06 Spring MVC and Request Life Cycle (0) 2020.02.03 Spring Bean Scopes (0) 2019.09.29