IOC (Inversion of Control) DI (Dependency Injection)

Inversion of Control is the core of Spring framework, which is used to reduce the coupling problem of computer programs. Dependency Injection is another term of IOC, which describes the same concept from different angles.

From the perspective of Spring container, Spring container is responsible for assigning the dependent object to the member variable of the caller, which is equivalent to injecting the instance it depends on for the caller, which is Spring dependency injection.

Control inversion is a way to generate or obtain specific objects through description (XML or annotation in Spring) and through a third party (creating object instances with new is not conducive to low coupling). In Spring, the IOC container implements control inversion, and its implementation method is dependency injection.

Spring IoC container

The design of Spring IoC container is mainly based on BeanFactory and ApplicationContext interfaces.

  • When creating an instance of BeanFactory, you need to provide the absolute path of the XML file. (this method is not commonly used)
public static void main(String[] args) {
		//Initialize the Spring container and load the configuration file
		XmlBeanFactory beanFac = new XmlBeanFactory(
new FileSystemResource("D:\\eclipse-workspace\\ch1\\src\\applicationContext.xml")
);
		//Get test instance through container
		TestDao tt = (TestDao)beanFac.getBean("test");
		tt.sayHello();
	}

  • There are three methods to create an ApplicationContext interface instance:

    1. Create through ClassPathXmlApplicationContext

    2. Create through FileSystemXmlApplicationContext

    3. Instantiate the ApplicationContext container through the Web server

1. Create through ClassPathXmlApplicationContext
ClassPathXmlApplicationContext will look for the specified XML configuration file from the classPath directory (src root directory).

public static void main(String[] args) {
		//Initialize the Spring container ApplicationContext and load the configuration file
		ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
		//Get test instance through container
		TestDao tt = (TestDao)appCon.getBean("test");
		tt.sayHello();
	}

2. Create through FileSystemXmlApplicationContext
FileSystemXmlApplicationContext will find the XML configuration file from the absolute path of the specified file, find and load it, and complete the instantiation of ApplicationContext.
Note: the method of using absolute path will lead to poor flexibility of the program. Everyone's workspace should be modified to the same, which is generally not recommended.

public static void main(String[] args) {
		//Initialize the Spring container ApplicationContext and load the configuration file
		ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
		//Get test instance through container
		TestDao tt = (TestDao)appCon.getBean("test");
		tt.sayHello();
	}

3. Instantiate the ApplicationContext container through the Web server
When the Web server instantiates the ApplicationContext container, it generally uses the implementation method based on org.springframework.web.context.ContextLoaderListener (spring-web-5.0.2.RELEASE.jar needs to be copied to the WEB-INF/lib directory). This method only needs to add the following code in web.xml:
Note: this method is very common!!!

<context-param>
  	<!-- load src Under directory applicationContext.xml file -->
  	<param-name>contextConfigLocation</param-name>
  	<param-value>
  		classpath:applicationContext.xml
  	</param-value>
  </context-param>
  <!-- Specify to ContextLoaderListener Mode start Spring container -->
  <listener>
  	<listener-class>
  		org.springframework.web.context.ContextLoaderListener
  	</listener-class>
  </listener>


Type of dependency injection

The method of implementing IoC container in Spring is dependency injection. The role of dependency injection is to dynamically inject its dependent objects (such as attribute values) into Bean components when creating objects using the Spring framework. There are usually two ways to implement dependency injection in Spring framework: construction method injection and property setter method injection.

Dependency injection: TestDIServiceImpl and TestDIServiceImpl1 depend on TestDIDao, which is injected into TestDIServiceImpl and TestDIServiceImpl1.

TestDIService.java

package service;

public interface TestDIService {
	public void sayHello();
}

TestDIServiceImpl.java

package service;

import dao.TestDIDao;

public class TestDIServiceImpl implements TestDIService {
	private TestDIDao testDIDao;//Declare an interface variable
	//Construction method for implementing dependency injection
	public TestDIServiceImpl(TestDIDao testDIDao) {
		super();
		this.testDIDao = testDIDao;
	}

	@Override
	public void sayHello() {
		// TODO Auto-generated method stub
		testDIDao.sayHello();
		System.out.println("TestDIService Construction method injection say:Hello!");
	}
}

TestDIServiceImpl1.java

package service;

import dao.TestDIDao;

public class TestDIServiceImpl1 implements TestDIService {
	private TestDIDao testDIDao;//Declare an interface variable
	//Add the setter method of testDIDao attribute to implement dependency injection
	public void setTestDIDao(TestDIDao testDIDao) {
		this.testDIDao = testDIDao;
	}

	@Override
	public void sayHello() {
		// TODO Auto-generated method stub
		testDIDao.sayHello();
		System.out.println("TestDIService1 setter Method injection say:Hello!");
	}
}

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.xsd">
       <!-- Class will be specified TestDIDaoImol Configure to Spring. Give Way Spring Create its instance -->
       <bean id="myTestDIDao" class="dao.TestDIDaoImpl"/>
       <!-- Injection using construction method -->
       <bean id="testDIService" class="service.TestDIServiceImpl">
       <!-- take myTestDIDao Inject into TestDIServiceImpl Properties of class testDIDao Come on. constructor-arg : Specifies the parameters of the constructor -->
       	<constructor-arg index="0" ref="myTestDIDao"/>
       </bean>
       <!-- use setter Method injection -->
       <bean id="testDIService1" class="service.TestDIServiceImpl1">
     	  <!-- call TestDIServiceImpl1 Class setter Method, will myTestDIDao Inject into TestDIServiceImpl1 Properties of class testDIDao upper -->
			<property name="testDIDao" ref="myTestDIDao"/>
       </bean>
</beans>

TestDI.java

package test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import service.TestDIService;

public class TestDI {
	public static void main(String[] args) {
		//Initialize the Spring container ApplicationContext. Load profile
		ApplicationContext appcon=new ClassPathXmlApplicationContext("applicationContext.xml");
		//Obtain the testservice instance through the container and test the construction method injection
		TestDIService ts=(TestDIService) appcon.getBean("testDIService");
		ts.sayHello();	
		//Obtain the testservice instance through the container and test the setter method injection
		TestDIService ts1=(TestDIService) appcon.getBean("testDIService1");
		ts1.sayHello();
	}
}

Tags: Java Spring Back-end

Posted on Tue, 26 Oct 2021 09:10:47 -0400 by BigTime