目录
1. Student 类代码、 Clazz 类代码、spring-ioc.xml 配置
五、依赖注入之为类类型的属性赋值(级联方式和内部 Bean)——(2025/2/25-19:21:20)肝不动了,剩下的明天(2024/2/26)再写
一、依赖注入之 Setter 注入
Setter 注入是通过调用类的 Setter 方法为属性赋值。
1. spring-ioc.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">
<!-- 未设置属性的 Bean -->
<bean id="studentOne" class="com.atguigu.spring.pojo.Student"></bean>
<!-- 使用 Setter 注入设置属性 -->
<bean id="studentTwo" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1001"></property>
<property name="sname" value="张三"></property>
<property name="age" value="23"></property>
<property name="gender" value="男"></property>
</bean>
</beans>
2. 测试代码
@Test
public void testDI(){
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Student student = ioc.getBean("studentTwo", Student.class);
System.out.println(student);
}
3. 输出结果
Student{sid=1001, sname='张三', age=23, gender='男'}
4. 解析
-
<property>
:通过 Setter 方法为属性赋值。-
name
:属性名(与 Setter 方法名对应,例如name="sid"
对应setSid
方法)。 -
value
:为属性设置的值。
-
二、依赖注入之构造器注入
演示一
构造器注入是通过调用类的构造方法为属性赋值。
1. spring-ioc.xml
配置
<bean id="studentThree" class="com.atguigu.spring.pojo.Student">
<constructor-arg value="1002"></constructor-arg>
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="24"></constructor-arg>
<constructor-arg value="女"></constructor-arg>
</bean>
2. 测试代码
@Test
public void testDI(){
//获取IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
//获取bean
Student student = ioc.getBean("studentThree", Student.class);
System.out.println(student);
}
3. 输出结果
Student{sid=1002, sname='李四', age=24, gender='女'}
进程已结束,退出代码为 0
4. 解析
-
<constructor-arg>
:通过构造方法为属性赋值。-
name
:构造方法参数名。 -
value
:为参数设置的值。
-
演示二
1. spring-ioc.xml
配置
<bean id="studentTwo" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1001"></property>
<property name="sname" value="张三"></property>
<property name="age" value="23" ></property>
<property name="gender" value="男"></property>
</bean>
<bean id="studentThree" class="com.atguigu.spring.pojo.Student">
<constructor-arg value="1002"></constructor-arg>
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="女"></constructor-arg>
<constructor-arg value="24" name="age"></constructor-arg>
</bean>
2. Student.java代码
package com.atguigu.spring.pojo;
public class Student implements Person {
private Integer sid;
private String sname;
private Integer age;
public String gender;
private Double score;
// 构造方法 1
public Student(Integer sid, String sname, String gender, Integer age) {
this.sid = sid;
this.sname = sname;
this.gender = gender;
this.age = age;
}
// 构造方法 2
public Student(Integer sid, String sname, String gender, Double score) {
this.sid = sid;
this.sname = sname;
this.gender = gender;
this.score = score;
}
// 无参构造方法
public Student() {
}
// Getter 和 Setter 方法
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", score=" + score +
'}';
}
}
3. 测试代码
@Test
public void testDI(){
//获取IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
//获取bean
Student student = ioc.getBean("studentThree", Student.class);
System.out.println(student);
}
4. 输出结果
Student{sid=1002, sname='李四', age=null, gender='女', score=24.0}
进程已结束,退出代码为 0
5.解析
-
构造器注入的灵活性:
-
如果类中有多个构造方法,Spring 会根据
<constructor-arg>
的参数数量和类型自动匹配对应的构造方法。 -
在
Student
类中,有两个构造方法:-
Student(Integer sid, String sname, String gender, Integer age)
-
Student(Integer sid, String sname, String gender, Double score)
-
-
在
spring-ioc.xml
中,studentThree
的配置匹配了第一个构造方法,因为age
是Integer
类型。
-
-
name
属性:-
在
<constructor-arg>
中使用name
属性可以明确指定参数名,避免参数顺序错误。 -
例如:
<constructor-arg value="24" name="age"></constructor-arg>
。
-
三、依赖注入之特殊值处理
1. 空值处理
在 Spring 中,可以通过以下两种方式为属性设置空值:
测试一:直接使用 value="null"
spring-ioc.xml
配置
<bean id="studentFour" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1003"></property>
<property name="sname" value="王五"></property>
<property name="gender" value="null"></property>
</bean>
测试代码
@Test
public void testDI(){
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Student student = ioc.getBean("studentFour", Student.class);
System.out.println(student);
}
输出结果
Student{sid=1003, sname='王五', age=null, gender='null', score=null}
解析
-
value="null"
:将gender
属性设置为字符串"null"
,而不是真正的null
值。 -
因此,
gender
的值是字符串"null"
,而不是 Java 中的null
。 -
注意:这种方式并不是真正的空值处理,而是将字符串
"null"
赋值给属性。
测试二:使用 <null/>
标签
spring-ioc.xml
配置
<bean id="studentFour" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1003"></property>
<property name="sname" value="王五"></property>
<property name="gender">
<null/>
</property>
</bean>
测试代码
@Test
public void testDI(){
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Student student = ioc.getBean("studentFour", Student.class);
System.out.println(student);
}
输出结果
Student{sid=1003, sname='王五', age=null, gender='null', score=null}
解析
-
<null/>
:将gender
属性设置为真正的null
值。 -
在输出结果中,
gender
显示为'null'
,这是因为toString()
方法将null
值转换为字符串"null"
。 -
注意:如果直接调用
gender
的方法(如toString()
),会抛出NullPointerException
。
2. 特殊字符处理
在 XML 中,某些字符(如 <
、>
、&
等)具有特殊含义,不能直接使用。以下是两种处理特殊字符的方式:
解决方案一:使用 XML 实体
XML 提供了一些预定义的实体来表示特殊字符,例如:
-
<
表示<
-
>
表示>
-
&
表示&
spring-ioc.xml
配置
<bean id="studentFour" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1003"></property>
<property name="sname" value="<王五>"></property>
<property name="gender">
<null/>
</property>
</bean>
输出结果
Student{sid=1003, sname='<王五>', age=null, gender='null', score=null}
解析
-
<
和>
:分别表示<
和>
。 -
Spring 会自动将 XML 实体转换为对应的字符。
解决方案二:使用 CDATA 节
CDATA 节用于表示纯文本数据,XML 解析器会忽略其中的特殊字符。
spring-ioc.xml
配置
<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1003"></property>
<property name="sname">
<value><![CDATA[《王五》]]></value>
</property>
<property name="gender">
<null/>
</property>
</bean>
测试代码
@Test
public void testDI(){
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Student student = ioc.getBean("studentFive", Student.class);
System.out.println(student);
}
输出结果
Student{sid=1003, sname='《王五》', age=null, gender='null', score=null}
解析
-
<![CDATA[ ... ]]>
:CDATA 节中的内容会被视为纯文本,不会被 XML 解析器解析。 -
适合处理包含大量特殊字符的文本。
四、依赖注入之为类类型的属性赋值(引用外部的 Bean)
1. Student
类代码、 Clazz
类代码、spring-ioc.xml
配置
Student
类代码
package com.atguigu.spring.pojo;
public class Student {
private Integer sid; // 学生 ID
private String sname; // 学生姓名
private Integer age; // 学生年龄
private String gender; // 学生性别
private Double score; // 学生成绩
private Clazz clazz; // 学生所属班级
// 构造方法、Getter 和 Setter 方法
// toString 方法
}
Clazz
类
package com.atguigu.spring.pojo;
public class Clazz {
private Integer cid; // 班级 ID
private String cname; // 班级名称
// 构造方法、Getter 和 Setter 方法
// toString 方法
}
spring-ioc.xml
配置
解析
-
<property name="clazz" ref="clazzOne">
:-
name="clazz"
:表示Student
类中的clazz
属性。 -
ref="clazzOne"
:引用 ID 为clazzOne
的 Bean。
-
-
Clazz
类:-
Clazz
是一个独立的类,表示班级信息,包含cid
(班级 ID)和cname
(班级名称)属性。
-
<!-- 定义 Student Bean -->
<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="26"></property>
<property name="gender" value="男"></property>
<!-- 引用外部的 Clazz Bean -->
<property name="clazz" ref="clazzOne"></property>
</bean>
<!-- 定义 Clazz Bean -->
<bean id="clazzOne" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="1111"></property>
<property name="cname" value="最强王者班"></property>
</bean>
2. 测试代码
@Test
public void testDI(){
//获取IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
//获取bean
Student student = ioc.getBean("studentFive", Student.class);
System.out.println(student);
}
3. 输出结果
Student{sid=1004, sname='赵六', age=26, gender='男', score=null, clazz=Clazz{cid=1111, cname='最强王者班'}}
进程已结束,退出代码为 0
4. 解析
-
类类型属性:
-
Student
类中的clazz
属性是Clazz
类型的对象。 -
通过
<property name="clazz" ref="clazzOne">
,将clazzOne
Bean 注入到Student
的clazz
属性中。
-
-
Bean 的引用:
-
使用
ref
属性引用外部 Bean。 -
ref="clazzOne"
表示引用 ID 为clazzOne
的 Bean。
-
-
输出结果:
-
Student
对象的clazz
属性被成功注入,值为Clazz{cid=1111, cname='最强王者班'}
。
-
五、依赖注入之为类类型的属性赋值(级联方式和内部 Bean)——(2025/2/25-19:21:20)肝不动了,剩下的明天(2024/2/26)再写
演示一:级联方式赋值(未初始化 clazz
属性)
spring-ioc.xml
配置
<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="26"></property>
<property name="gender" value="男"></property>
<!-- 级联方式赋值 -->
<property name="clazz.cid" value="2222"></property>
<property name="clazz.cname" value="远大前程班"></property>
</bean>
<bean id="clazzOne" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="1111"></property>
<property name="cname" value="最强王者班"></property>
</bean>
测试代码
@Test
public void testDI(){
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Student student = ioc.getBean("studentFive", Student.class);
System.out.println(student);
}
输出结果
二月 26, 2025 11:29:04 上午 org.springframework.context.support.AbstractApplicationContext refresh
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'studentFive' defined in class path resource [spring-ioc.xml]: Error setting property values; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'clazz' of bean class [com.atguigu.spring.pojo.Student]: Value of nested property 'clazz' is null
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'studentFive' defined in class path resource [spring-ioc.xml]: Error setting property values; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'clazz' of bean class [com.atguigu.spring.pojo.Student]: Value of nested property 'clazz' is null
分析
-
问题原因:
-
在
Student
类中,clazz
属性未初始化(即null
)。 -
尝试通过
clazz.cid
和clazz.cname
为clazz
的属性赋值时,由于clazz
为null
,导致抛出NullValueInNestedPathException
异常。
-
-
解决方案:
-
需要先初始化
clazz
属性,例如通过引用外部 Bean 或内部 Bean。
-
演示二:级联方式赋值(初始化 clazz
属性)
spring-ioc.xml
配置
<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="26"></property>
<property name="gender" value="男"></property>
<!-- 引用外部 Bean -->
<property name="clazz" ref="clazzOne"></property>
<!-- 级联方式赋值 -->
<property name="clazz.cid" value="2222"></property>
<property name="clazz.cname" value="远大前程班"></property>
</bean>
<bean id="clazzOne" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="1111"></property>
<property name="cname" value="最强王者班"></property>
</bean>
测试代码
@Test
public void testDI(){
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Student student = ioc.getBean("studentFive", Student.class);
System.out.println(student);
}
输出结果
Student{sid=1004, sname='赵六', age=26, gender='男', score=null, clazz=Clazz{cid=2222, cname='远大前程班'}}
分析
-
关键点:
-
通过
<property name="clazz" ref="clazzOne">
初始化了clazz
属性。 -
然后通过
<property name="clazz.cid" value="2222">
和<property name="clazz.cname" value="远大前程班">
修改了clazz
的属性值。
-
-
结果:
-
clazz
的属性值被成功修改为Clazz{cid=2222, cname='远大前程班'}
。
-
演示三:内部 Bean 赋值
spring-ioc.xml
配置
<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="26"></property>
<property name="gender" value="男"></property>
<!-- 内部 Bean -->
<property name="clazz">
<bean class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="2222"></property>
<property name="cname" value="远大前程"></property>
</bean>
</property>
</bean>
测试代码
@Test
public void testDI(){
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Student student = ioc.getBean("studentFive", Student.class);
System.out.println(student);
}
输出结果
Student{sid=1004, sname='赵六', age=26, gender='男', score=null, clazz=Clazz{cid=2222, cname='远大前程'}}
分析
-
关键点:
-
使用
<property name="clazz">
定义了一个内部 Bean。 -
内部 Bean 只能在当前 Bean 的内部使用,无法通过 IOC 容器直接获取。
-
-
结果:
-
clazz
属性被成功注入,值为Clazz{cid=2222, cname='远大前程'}
。
-
演示四:内部 Bean 无法直接获取
spring-ioc.xml
配置
<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="26"></property>
<property name="gender" value="男"></property>
<!-- 内部 Bean -->
<property name="clazz">
<bean id="clazzInner" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="2222"></property>
<property name="cname" value="远大前程"></property>
</bean>
</property>
</bean>
测试代码
@Test
public void testDI() {
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 尝试获取内部 Bean
Clazz clazz = ioc.getBean("clazzInner", Clazz.class);
System.out.println(clazz);
}
输出结果
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'clazzInner' available
分析
-
关键点:
-
内部 Bean 只能在当前 Bean 的内部使用,无法通过 IOC 容器直接获取。
-
即使为内部 Bean 指定了
id
,也无法通过ioc.getBean()
获取。
-
-
结果:
-
抛出
NoSuchBeanDefinitionException
异常。
-
2025/2/26-11:12
六、依赖注入之为数组类型的属性赋值
在 Spring 中,可以通过 <array>
标签为数组类型的属性赋值。以下是详细解析和示例。
1. spring-ioc.xml
配置
<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="26"></property>
<property name="gender" value="男"></property>
<!-- 为数组类型的 hobby 属性赋值 -->
<property name="hobby">
<array>
<value>抽烟</value>
<value>喝酒</value>
<value>烫头</value>
</array>
</property>
<!-- 内部 Bean -->
<property name="clazz">
<bean id="clazzInner" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="2222"></property>
<property name="cname" value="远大前程"></property>
</bean>
</property>
</bean>
解析
-
<array>
标签:-
用于为数组类型的属性赋值。
-
每个
<value>
标签表示数组中的一个元素。
-
-
hobby
属性:-
在
Student
类中,hobby
是一个数组类型的属性(如String[]
)。 -
通过
<array>
标签为其赋值,值为["抽烟", "喝酒", "烫头"]
。
-
-
内部 Bean:
-
clazz
属性通过内部 Bean 的方式赋值,值为Clazz{cid=2222, cname='远大前程'}
。
-
2. Student
类
public class Student {
private Integer sid; // 学生 ID
private String sname; // 学生姓名
private Integer age; // 学生年龄
private String gender; // 学生性别
private Double score; // 学生成绩
private String[] hobby; // 学生爱好(数组类型)
private Clazz clazz; // 学生所属班级
// Getter 和 Setter 方法
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
public Clazz getClazz() {
return clazz;
}
public void setClazz(Clazz clazz) {
this.clazz = clazz;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", score=" + score +
", hobby=" + Arrays.toString(hobby) +
", clazz=" + clazz +
'}';
}
}
解析
-
hobby
属性:-
类型为
String[]
,用于存储学生的多个爱好。
-
-
clazz
属性:-
类型为
Clazz
,表示学生所属的班级。
-
3. 测试代码
@Test
public void testDI() {
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Student student = ioc.getBean("studentFive", Student.class);
System.out.println(student);
}
4. 输出结果
Student{sid=1004, sname='赵六', age=26, gender='男', score=null, hobby=[抽烟, 喝酒, 烫头], clazz=Clazz{cid=2222, cname='远大前程'}}
解析
-
hobby
属性:-
成功注入了数组值
["抽烟", "喝酒", "烫头"]
。
-
-
clazz
属性:-
成功注入了内部 Bean,值为
Clazz{cid=2222, cname='远大前程'}
。
-
5. 分析
关键点
-
数组类型属性赋值:
-
使用
<array>
标签可以为数组类型的属性赋值。 -
每个
<value>
标签表示数组中的一个元素。
-
-
内部 Bean:
-
内部 Bean 只能在当前 Bean 的内部使用,无法通过 IOC 容器直接获取。
-
-
类型匹配:
-
确保
hobby
属性的类型与配置中的赋值类型一致(如String[]
)。
-
优点
-
灵活性:
-
可以轻松为数组类型的属性赋值,支持多个值。
-
-
可读性:
-
使用
<array>
标签使配置更加直观和易读。
-
2025/2/26-12:28:03
七、依赖注入之为 List 集合类型的属性赋值
演示一:直接使用 <list>
标签
1. spring-ioc.xml
配置
<bean id="clazzOne" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="1111"></property>
<property name="cname" value="最强王者班"></property>
<!-- 为 List 类型的 students 属性赋值 -->
<property name="students">
<list>
<ref bean="studentOne"></ref>
<ref bean="studentTwo"></ref>
<ref bean="studentThree"></ref>
</list>
</property>
</bean>
2. Clazz
类
public class Clazz {
private Integer cid; // 班级 ID
private String cname; // 班级名称
private List<Student> students; // 学生列表
// Getter 和 Setter 方法
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Clazz{" +
"cid=" + cid +
", cname='" + cname + '\'' +
", students=" + students +
'}';
}
}
3. 测试代码
@Test
public void testDI() {
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Clazz clazz = ioc.getBean("clazzOne", Clazz.class);
System.out.println(clazz);
}
4. 输出结果
Clazz{cid=1111, cname='最强王者班', students=[Student{sid=null, sname='null', age=null, gender='null', score=null, hobby=null, clazz=null}, Student{sid=1001, sname='张三', age=23, gender='男', score=null, hobby=null, clazz=null}, Student{sid=1002, sname='李四', age=24, gender='女', score=null, hobby=null, clazz=null}]}
5. 分析
-
<list>
标签:-
用于为
List
集合类型的属性赋值。 -
每个
<ref>
标签表示List
中的一个元素,引用其他 Bean。
-
-
students
属性:-
成功注入了
List<Student>
,包含studentOne
、studentTwo
和studentThree
。
-
-
注意:
-
如果
studentOne
、studentTwo
和studentThree
的某些属性未赋值,输出结果中会显示为null
。
-
演示二:使用 <util:list>
标签
1. spring-ioc.xml
配置
<!-- 引入 util 命名空间 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="clazzOne" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="1111"></property>
<property name="cname" value="最强王者班"></property>
<!-- 引用外部的 List Bean -->
<property name="students" ref="studentList"></property>
</bean>
<!-- 配置一个集合类型的 Bean -->
<util:list id="studentList">
<ref bean="studentOne"></ref>
<ref bean="studentTwo"></ref>
<ref bean="studentThree"></ref>
</util:list>
</beans>
2. 测试代码
@Test
public void testDI() {
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Clazz clazz = ioc.getBean("clazzOne", Clazz.class);
System.out.println(clazz);
}
3. 输出结果
Clazz{cid=1111, cname='最强王者班', students=[Student{sid=null, sname='null', age=null, gender='null', score=null, hobby=null, clazz=null}, Student{sid=1001, sname='张三', age=23, gender='男', score=null, hobby=null, clazz=null}, Student{sid=1002, sname='李四', age=24, gender='女', score=null, hobby=null, clazz=null}]}
4. 分析
-
<util:list>
标签:-
用于定义一个独立的
List
Bean,可以在多个地方引用。 -
需要引入
util
命名空间。
-
-
students
属性:-
通过
ref="studentList"
引用外部的List
Bean。 -
成功注入了
List<Student>
,包含studentOne
、studentTwo
和studentThree
。
-
-
优点:
-
提高配置的复用性,适合多个 Bean 共享同一个集合。
-
八、依赖注入之为 Map 集合类型的属性赋值
1. spring-ioc.xml
配置
<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="26"></property>
<property name="gender" value="男"></property>
<!-- 为 Map 类型的 teacherMap 属性赋值 -->
<property name="teacherMap">
<map>
<entry key="10086" value-ref="teacherOne"></entry>
<entry key="10010" value-ref="teacherTwo"></entry>
</map>
</property>
</bean>
<!-- 定义 Teacher Bean -->
<bean id="teacherOne" class="com.atguigu.spring.pojo.Teacher">
<property name="tid" value="10086"></property>
<property name="tname" value="大宝"></property>
</bean>
<bean id="teacherTwo" class="com.atguigu.spring.pojo.Teacher">
<property name="tid" value="10010"></property>
<property name="tname" value="二宝"></property>
</bean>
解析
-
<map>
标签:-
用于为
Map
集合类型的属性赋值。 -
每个
<entry>
标签表示Map
中的一个键值对。-
key
:键的值。 -
value-ref
:引用其他 Bean 作为值。
-
-
-
teacherMap
属性:-
在
Student
类中,teacherMap
是一个Map
类型的属性(如Map<String, Teacher>
)。 -
通过
<map>
标签为其赋值,值为{"10086": teacherOne, "10010": teacherTwo}
。
-
2. Student
类
public class Student {
private Integer sid; // 学生 ID
private String sname; // 学生姓名
private Integer age; // 学生年龄
private String gender; // 学生性别
private Map<String, Teacher> teacherMap; // 教师 Map
// Getter 和 Setter 方法
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Map<String, Teacher> getTeacherMap() {
return teacherMap;
}
public void setTeacherMap(Map<String, Teacher> teacherMap) {
this.teacherMap = teacherMap;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", teacherMap=" + teacherMap +
'}';
}
}
解析
-
teacherMap
属性:-
类型为
Map<String, Teacher>
,用于存储学生的教师信息。 -
键为教师 ID(
String
类型),值为Teacher
对象。
-
3. Teacher
类
public class Teacher {
private Integer tid; // 教师 ID
private String tname; // 教师姓名
// Getter 和 Setter 方法
public Integer getTid() {
return tid;
}
public void setTid(Integer tid) {
this.tid = tid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
@Override
public String toString() {
return "Teacher{" +
"tid=" + tid +
", tname='" + tname + '\'' +
'}';
}
}
4. 测试代码
@Test
public void testDI() {
// 获取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
// 获取 Bean
Student student = ioc.getBean("studentFive", Student.class);
System.out.println(student);
}
5. 输出结果
Student{sid=1004, sname='赵六', age=26, gender='男', teacherMap={10086=Teacher{tid=10086, tname='大宝'}, 10010=Teacher{tid=10010, tname='二宝'}}}
6. 分析
关键点
-
<map>
标签:-
用于为
Map
集合类型的属性赋值。 -
每个
<entry>
标签表示Map
中的一个键值对。
-
-
teacherMap
属性:-
成功注入了
Map<String, Teacher>
,包含两个键值对:-
"10086"
对应Teacher{tid=10086, tname='大宝'}
。 -
"10010"
对应Teacher{tid=10010, tname='二宝'}
。
-
-
-
类型匹配:
-
确保
teacherMap
属性的类型与配置中的赋值类型一致(如Map<String, Teacher>
)。
-
优点
-
灵活性:
-
可以轻松为
Map
类型的属性赋值,支持复杂的键值对结构。
-
-
可读性:
-
使用
<map>
标签使配置更加直观和易读。
-
九、依赖注入之 p 命名空间
1. 简介:
-
目的:简化 XML 配置,通过属性(而非嵌套标签)注入依赖。
-
适用场景:适用于简单属性(基本类型、字符串)或直接 Bean 引用。
2. 配置示例:
<!-- 传统方式 -->
<bean id="student" class="com.example.Student">
<property name="sname" value="张三"/>
<property name="teacher" ref="teacherOne"/>
</bean>
<!-- 使用 p 命名空间 -->
<bean id="student" class="com.example.Student"
p:sname="张三"
p:teacher-ref="teacherOne"/>
3. 关键点:
-
启用 p 命名空间:需在 XML 头部添加
xmlns:p="http://www.springframework.org/schema/p"
。 -
语法规则:
-
基本类型:
p:属性名="值"
-
Bean 引用:
p:属性名-ref="Bean ID"
-
-
局限性:不支持复杂类型(如 Map、List),需结合传统
<property>
标签使用。
4. 优点:
-
简洁性:减少嵌套标签,提升可读性。
-
直观性:属性直接对应类字段,配置更直观。
这两天太浮躁摆烂了,学不下去,今天(2025/2/26-22:22:22)没怎么学习,自我安慰......
明天真要好好开始认真学习了,补回来QAQ......