Spring01_ioc (Inversion of Control) 控制反轉
控制反轉示例:
- 新建 Maven ⼯程,pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.blu</groupId>
<artifactId>Spring01ioc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
- 創建實體類Student
package com.blu.entity;
import lombok.Data;
@Data
public class Student {
private long id;
private String name;
private int age;
}
- 在resources目錄下創建spring配置文件spring.xml,添加Student對象並賦值:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="student" class="com.blu.entity.Student">
<property name="id" value="1"></property>
<property name="name" value="張三"></property>
<property name="age" value="22"></property>
</bean>
</beans>
- 測試通過ioc方式獲取該對象:
package com.blu.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.blu.entity.Student;
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);
}
}
- 運行結果:
Student(id=1, name=張三, age=22)
注:交給ioc容器管理的類必須要有無參構造!(因爲Spring底層是通過反射機制來創建對象的,調用的是無參構造函數)。
property標籤的value屬性值必須是基本數據類型或String類型。
依賴注入DI(Dependency Injection)示例:
- 創建實體類Address
package com.blu.entity;
import lombok.Data;
@Data
public class Address {
private long id;
private String name;
}
- 修改實體類Student
package com.blu.entity;
import lombok.Data;
@Data
public class Student {
private long id;
private String name;
private int age;
private Address address;
}
- 修改配置文件spring.xml
利用ref屬性在一個bean中引入另一個bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="student" class="com.blu.entity.Student">
<property name="id" value="1"></property>
<property name="name" value="張三"></property>
<property name="age" value="22"></property>
<property name="address" ref="address"></property>
</bean>
<bean id="address" class="com.blu.entity.Address">
<property name="id" value="1"></property>
<property name="name" value="江蘇南京"></property>
</bean>
</beans>
- 測試通過ioc方式獲取Student對象:
package com.blu.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.blu.entity.Student;
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);
}
}
- 結果(Address被成功注入):
Student(id=1, name=張三, age=22, address=Address(id=1, name=江蘇南京))
通過運行時類獲取bean
- 測試方法和運行結果:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Student student = (Student) applicationContext.getBean(Student.class);
System.out.println(student);
Student(id=1, name=張三, age=22, address=Address(id=1, name=江蘇南京))
注:通過該方式獲取bean,要求配置文件中的對象只能有唯一一個bean,否則會拋異常。
通過有參構造函數創建bean
- 修改Student實體類(增加全參構造函數):
package com.blu.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private long id;
private String name;
private int age;
private Address address;
}
- 修改配置文件(通過有參構造創建bean):
<bean id="student" class="com.blu.entity.Student">
<constructor-arg value="2"></constructor-arg>
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="18"></constructor-arg>
<constructor-arg ref="address"></constructor-arg>
</bean>
- 運行結果:
Student(id=2, name=李四, age=18, address=Address(id=1, name=江蘇南京))
注:constructor-arg標籤的value屬性必須按照有參構造函數的參數順序來寫,或者通過index屬性來確定順序,例如:
<bean id="student" class="com.blu.entity.Student">
<constructor-arg index="0" value="3"></constructor-arg>
<constructor-arg index="2" value="18"></constructor-arg>
<constructor-arg index="1" value="小明"></constructor-arg>
<constructor-arg index="3" ref="address"></constructor-arg>
</bean>
給bean注入集合屬性
示例:
- Student實體類:
package com.blu.entity;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private long id;
private String name;
private int age;
private List<Address> addresses;
}
- Address實體類:
package com.blu.entity;
import lombok.Data;
@Data
public class Address {
private long id;
private String name;
}
- 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="student" class="com.blu.entity.Student">
<property name="id" value="1"></property>
<property name="name" value="張三"></property>
<property name="age" value="22"></property>
<property name="addresses">
<list>
<ref bean="address"></ref>
<ref bean="address2"></ref>
</list>
</property>
</bean>
<bean id="address" class="com.blu.entity.Address">
<property name="id" value="1"></property>
<property name="name" value="江蘇南京"></property>
</bean>
<bean id="address2" class="com.blu.entity.Address">
<property name="id" value="2"></property>
<property name="name" value="安徽合肥"></property>
</bean>
</beans>
- 測試和結果
package com.blu.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.blu.entity.Student;
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);
}
}
Student(id=1, name=張三, age=22, addresses=[Address(id=1, name=江蘇南京), Address(id=2, name=安徽合肥)])
利用p命名空間簡化bean的配置
示例:
<bean id="student" class="com.blu.entity.Student" p:id="1" p:name="張三" p:age="22" p:address-ref="address"></bean>
<bean id="address" class="com.blu.entity.Address" p:id="2" p:name="江蘇南京"></bean>