Spring Study Notes: IoC

SummarySpring 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. IoC—Inversion of Control, also known as dependency injection—is an important object-oriented principle for reducing program coupling and is central to Spring…

springjava

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:

JAVA
public void test(){
		System.out.println("张三 - 测试员工");
	}

Another class isJavaWork, which contains adoTestmethod, which callsZhangSan.javaandLiSi.javaoftestmethod, shown below:

JAVA
public void doTest(){
		ZhangSan zhangsan = new ZhangSan();
		zhangsan.test();
	}

The main function now contains:

JAVA
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:

1.jpg

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

img.png

Applying IoC to the previous example introduces a Spring configuration file:beans.xml. A standard beans.xml file looks like this:

XML
<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.

Declares an XML Schema instance, enabling the schemaLocation attribute.

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:

XML
<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:

JAVA
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:

JAVA
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:

JAVA
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 + "]";
	}


}

JAVA
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:

JAVA
	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:

XML
<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:

JAVA
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:

XML
<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:

JAVA
	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:

XML
<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:

JAVA
	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:

XML
<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:

JAVA
	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:

JAVA
public class PeopleFactory {

	public People createPeople(){

		People p = new People();
		p.setId(5);
		p.setName("小五");
		p.setAge(55);
		return p;
	}

}

beans.xmlConfiguration:

XML
<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:

JAVA
	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:

JAVA
public class PeopleFactory2 {

	public static People createPeople(){

		People p = new People();
		p.setId(6);
		p.setName("六六");
		p.setAge(66);
		return p;
	}
}

beans.xmlConfiguration:

XML
<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:

JAVA
	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