Spring Study Notes: IoC
Preface
As I begin studying Java code auditing, I am first learning the ideas and programming patterns behind Spring. These notes record that process, and corrections are welcome.
IOC
IoC, or Inversion of Control—also known as dependency injection—is an important object-oriented principle for reducing coupling and is central to the lightweight Spring framework.
IoC is an idea rather than a technology. In Java, it means handing designed objects to a container for control instead of controlling them from within the objects. For example:
There are two classes:ZhangSan.javaandLiSi.java. Both classes contain the sametestmethod, as follows:
public void test(){
System.out.println("张三 - 测试员工");
}
Another class isJavaWork, which contains adoTestmethod, which callsZhangSan.javaandLiSi.javaoftestmethod, shown below:
public void doTest(){
ZhangSan zhangsan = new ZhangSan();
zhangsan.test();
}
The main function now contains:
public static void main(String[] args) {
JavaWork javawork = new JavaWork();
javawork.setTester(new LiSi());
javawork.doTest();
}
This is the conventional approach in which control remains inside the object. Its flow is:

How, then, does IoC provide control? The following diagram illustrates it.

Applying IoC to the previous example introduces a Spring configuration file:beans.xml. A standard beans.xml file looks like this:
<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">
</beans>
Explanation:
Declares the default namespace for the XML file; tags without another namespace use this namespace.
- 【xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"】
Declares an XML Schema instance, enabling the schemaLocation attribute.
- 【xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd】
Specifies the Schema location. This attribute must be used with a namespace.
This attribute has two values: the namespace to use and the location of the XML Schema for that namespace.
Using IoC, we can definebeans.xmlIts contents are:
<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">
<bean id="zhangsan" class="com.java001.service.ZhangSan"></bean>
<bean id="lisi" class="com.java001.service.LiSi"></bean>
<bean id="javawork" class="com.java001.service.JavaWork">
<property name="tester" ref="zhangsan"></property>
</bean>
</beans>
We only need to modify the following in the configuration file:<property name="tester" ref="zhangsan"></property>to control which class is invoked without placing that control inside the object.
After defining the configuration, modify main as follows:
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
JavaWork javawork = (JavaWork)ac.getBean("javawork");
javawork.doTest();
}
Load this XML configuration file and invokedoTestmethod without needing to modifyjavawork.setTester(new LiSi());to change the object that should be invoked.
Dependency Injection
Before discussing dependency injection, define dependency. A dependency is a relationship in which one class contains a reference to another. If class People contains a reference to class Dog, People depends on Dog:
class People{
Dog dog;
public People(){
dog = new Dog();
}
}
Now consider dependency injection. When first learning Java, how would we provide a Dog reference to the constructor above?
Our first instinct is to create an object with new. That reflects the conventional model in which the caller constructs the callee. With dependency injection, we do not instantiate the object directly; an external reference supplies the dependency. This keeps cooperating components loosely coupled. In plain terms, pass in the needed value instead of modifying the related class.
This section introduces property injection, constructor injection, and factory-method injection. Generic dependency injection can wait until later.
There are two classes:People.javaandDog.java, whose contents are:
package com.java002.entity;
public class People {
private int id;
private String name;
private int age;
public People() {
super();
// TODO Auto-generated constructor stub
}
public People(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "People [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
package com.java002.entity;
public class Dog {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The main function is:
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
People people = (People)ac.getBean("people");
System.out.println(people);
}
Property Injection
beans.xmlConfiguration:
<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">
<bean id="people2" class="com.java002.entity.People">
<property name="id" value="2"></property>
<property name="name" value="李二"></property>
<property name="age" value="22"></property>
</bean>
</beans>
Modify the main function as follows:
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
People people = (People)ac.getBean("people");
System.out.println(people);
// setter injection
People people2 = (People)ac.getBean("people2");
System.out.println(people2);
}
Constructor Injection
Constructor injection has three forms: by type, by index, or by a combination of type and index.
by type
beans.xmlConfiguration:
<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">
<bean id="people3" class="com.java002.entity.People">
<constructor-arg type="int" value="3"></constructor-arg>
<constructor-arg type="String" value="三三"></constructor-arg>
<constructor-arg type="int" value="33"></constructor-arg>
</bean>
</beans>
Modify the main function as follows:
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
People people = (People)ac.getBean("people");
System.out.println(people);
// constructor injection
People people3 = (People)ac.getBean("people3");
System.out.println(people3);
}
by index
beans.xmlConfiguration:
<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">
<bean id="people4" class="com.java002.entity.People">
<constructor-arg index="0" value="4"></constructor-arg>
<constructor-arg index="1" value="赵四"></constructor-arg>
<constructor-arg index="2" value="44"></constructor-arg>
</bean>
</beans>
Modify the main function as follows:
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
People people = (People)ac.getBean("people");
System.out.println(people);
// index-based injection
People people4 = (People)ac.getBean("people4");
System.out.println(people4);
}
using type and index together
beans.xmlConfiguration:
<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">
<bean id="people3_4" class="com.java002.entity.People">
<constructor-arg index="0" type="int" value="4"></constructor-arg>
<constructor-arg index="1" type="String" value="赵四"></constructor-arg>
<constructor-arg index="2" type="int" value="44"></constructor-arg>
</bean>
</beans>
Modify the main function as follows:
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
People people = (People)ac.getBean("people");
System.out.println(people);
// combined injection
People people3_4 = (People)ac.getBean("people3_4");
System.out.println(people3_4);
}
Factory-Method Injection
Factory-method injection is likewise divided into non-static and static methods.
Non-Static
Create a factory class.PeopleFactory.java, containing:
public class PeopleFactory {
public People createPeople(){
People p = new People();
p.setId(5);
p.setName("小五");
p.setAge(55);
return p;
}
}
beans.xmlConfiguration:
<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">
<bean id="peoplefactory" class="com.java002.factory.PeopleFactory"></bean>
<bean id="people5" factory-bean="peoplefactory" factory-method="createPeople"></bean>
</beans>
Modify the main function as follows:
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
People people = (People)ac.getBean("people");
System.out.println(people);
// factory-method injection (non-static)
People people5 = (People)ac.getBean("people5");
System.out.println(people5);
}
Static
Create a factory class.PeopleFactory2.java, containing:
public class PeopleFactory2 {
public static People createPeople(){
People p = new People();
p.setId(6);
p.setName("六六");
p.setAge(66);
return p;
}
}
beans.xmlConfiguration:
<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">
<bean id="people6" class="com.java002.factory.PeopleFactory2" factory-method="createPeople"></bean>
</beans>
Modify the main function as follows:
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
People people = (People)ac.getBean("people");
System.out.println(people);
// factory-method injection (static)
People people6 = (People)ac.getBean("people6");
System.out.println(people6);
}
References
https://www.iteye.com/blog/jinnianshilongnian-1413846
https://blog.csdn.net/carson0408/article/details/79019400
https://baijiahao.baidu.com/s?id=1612405553596190826&wfr=spider&for=pc