依赖注入
Spring可以为所依赖的属性进行赋值,这个过程被称为依赖注入
Student.java
public class Student {
private Integer id;
private String name;
private Integer age;
private String sex;
}
//省略无参构造、满参构造、set、get、toString方法
Student依赖于id、name、age、sex属性
setter注入
通过调用Bean中的set方法为属性进行赋值
applicationContext.xml
<bean id="Student" class="com.atguigu.spring.Student">
<!--
property标签:通过组件类的setXxx()方法给组件对象设置属性
name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关)
value属性:指定属性值
-->
<property name="id" value="10"></property>
<property name="name" value="yu"></property>
<property name="age" value="18"></property>
<property name="sex" value="男"></property>
</bean>
Student{id=10, name='yu', age=18, sex='男'}
构造器注入
通过调用Bean中的构造器为属性进行赋值
applicationContext.xml
<bean id="StudentOne" class="com.atguigu.spring.Student">
<!--
这里会自动匹配有四个参数且赋值属性可以匹配的构造方法,可以省略name属性
如果有多个可以匹配的构造方法,也就是赋值的属性(20)可以通用(Integer age和Double age1),此时可以通过name进行指定(name="age")
-->
<constructor-arg value="100"></constructor-arg>
<constructor-arg value="xin"></constructor-arg>
<constructor-arg value="20"></constructor-arg>
<constructor-arg value="女"></constructor-arg>
</bean>
Student{id=100, name='xin', age=20, sex='女'}
constructor-arg标签可以通过两个属性进一步描述构造器参数:
index属性:指定参数所在位置的索引(从0开始)
name属性:指定参数名
特殊值处理
字面量赋值
int a = 10;
声明一个变量a,初始化为10,此时a就不代表字母a了,而是作为一个变量的名字。
当引用a的时候,实际上拿到的值是10
而如果a是带引号的:‘a’,那么它现在不是一个变量,它就是代表a这个字母本身,这就是字面量。所以字面量没有引申含义,就是看到的这个数据本身。
使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量
需要对一些特殊值进行处理
null值
applicationContext.xml
<!--这样的写法,为name所赋的值是字符串"null"-->
<property name="name" value="null"></property>
<!--需要使用空标签<null>设置为"null"值-->
<property name="name">
<null/>
</property>
XML实体
小于号在XML文档中用来定义标签的开始,不能随便使用,可以使用对应的XML实体来代替
<property name="expression" value="a < b"/>
常用的XML实体:
<:<
>:>
&:&
CDATA节
CDATA中的C代表Character,是文本、字符的含义,CDATA就表示纯文本数据, XML解析器看到CDATA节就知道这里是纯文本,就不会当作XML标签或属性来解析,CDATA节后面的"[]"中可以写任意的文本内容
applicationContext.xml
<bean id="StudentTwo" class="com.atguigu.spring.Student">
<property name="id" value="10"></property>
<property name="name">
<null></null>
</property>
<property name="sex" value="a < b"></property>
<!--IDEA在标签内大写CD即可跳出提示CDATA提示-->
<property name="age">
<value><![CDATA[24]]></value>
</property>
</bean>
效果:
Student{id=10, name='null', age=24, sex='a < b'}
类(class)类型属性赋值
创建一个班级类——Classes
public class Classes {
private Integer cid;
private String cname;
}
在Student类中添加此属性——classes
引入外部bean(ref属性)
在<property>
内通过<ref>
引入另外一个bean的id实现引入赋值
applicationContext.xml
<bean id="StudentThree" class="com.atguigu.spring.Student">
<property name="id" value="5"></property>
<property name="name" value="yu"></property>
<property name="age" value="80"></property>
<property name="sex" value="男"></property>
<!--ref:引用IOC容器中某个bean的id-->
<property name="classes" ref="Class"></property>
</bean>
<bean id="Class" class="com.atguigu.spring.Classes">
<property name="cid" value="1"></property>
<property name="cname" value="一班"></property>
</bean>
级联方式("."
)
通过"."
的方式可以选择下级属性
<property name="classes" ref="Class"></property>
<!--需要先为class属性赋初值,否则会出现空指针异常,赋初值后通过级联方式进行二次修改-->
<property name="classes.cid" value="2"></property>
<property name="classes.cname" value="二班"></property>
内部bean(<bean>
)
相当于将属性拆为一个bean,在<property>
下添加<bean>
标签
<property name="classes">
<!--内部bean,只能在当前bean内部使用,不能直接通过IOC容器获取-->
<bean id="ClassOne" class="com.atguigu.spring.Classes">
<property name="cid" value="3"></property>
<property name="cname" value="三班"></property>
</bean>
</property>
数组类型属性赋值(<array>
)
Student.java中添加属性private String[] strings
在<property>
内通过<array>
属性为数组赋值,<value>
按字面量赋值(一个标签对应一个数组存储内容)
<property name="strings">
<array>
<value>你</value>
<value>好</value>
<value>世界</value>
</array>
</property>
Student.java中添加属性private Classes[] clas
<!--为类数组赋值可以使用<ref>和<bean>为数组的变量赋初值-->
<property name="clas">
<array>
<ref bean="Class"></ref>
<ref bean="Class"></ref>
<bean id="ClassTest" class="com.atguigu.spring.Classes">
<property name="cid" value="1"></property>
<property name="cname" value="一班"></property>
</bean>
</array>
</property>
list集合类型属性赋值
删除学生类(Student)中的属性private Classes[] clas
,为班级类(Classes)添加一个属性private List<Student> students
使用<list>
标签
在<property>
内通过<list>
属性为数组赋值,使用<ref>
和<bean>
为链表的内的类赋初值(一个标签对应一个数组存储内容)
<property name="students">
<list>
<ref bean="StudentOne"></ref>
<ref bean="StudentTwo"></ref>
</list>
</property>
使用<util:list>
约束
在创建约束后通过ref
属性直接引入<property>
内即可
<bean id="ClassOne" class="com.atguigu.spring.Classes">
<property name="cid" value="1"></property>
<property name="cname" value="一班"></property>
<property name="students" ref="StudentList"></property>
</bean>
<!--使用util约束(按照IDEA导入提示约束),配置一个list集合类型的bean-->
<util:list id="StudentList">
<!--这里可以通过ref引入外部创建好的bean,也可以手动创建bean-->
<ref bean="StudentOne"></ref>
<ref bean="StudentTwo"></ref>
</util:list>
map集合类型属性赋值
创建教师类(Teacher),属性为tid 和 tname
,在学生类(Student)中添加属性为private Map<String,Teacher> teacher
使用<map>
标签
通过<entry>
标签设置键值对
<property name="teacher">
<map>
<!--
entry:键值对
key:键
value-ref:引入外部bean的值
-->
<entry key="teacher" value-ref="teacher"></entry>
</map>
</property>
使用<util:map>
约束
在创建约束后通过ref
属性引入<property>
内即可
<bean id="StudentThree" class="com.atguigu.spring.Student">
<property name="id" value="5"></property>
<property name="name" value="yu"></property>
<property name="age" value="80"></property>
<property name="sex" value="男"></property>
<property name="classes">
<!--内部bean,只能在当前bean内部使用,不能直接通过IOC容器获取-->
<bean id="ClassOne" class="com.atguigu.spring.Classes">
<property name="cid" value="3"></property>
<property name="cname" value="三班"></property>
</bean>
</property>
<property name="teacher" ref="TeacherMap"></property>
</bean>
<!--创建teacher相关的bean-->
<bean id="teacher" class="com.atguigu.spring.Teacher">
<property name="tid" value="12"></property>
<property name="tname" value="张三"></property>
</bean>
<!--使用util约束(按照IDEA导入提示约束),配置一个map集合类型的bean-->
<util:map id="TeacherMap">
<entry key="teacher" value-ref="teacher"></entry>
</util:map>
p命名空间
创建p命名空间,需要对应的约束,引入后可以通过<p:>
为属性赋值
<!--引入p命名空间后,p中会有每个属性对应的value(tid)和ref(tid-ref)赋值方式-->
<bean id="teacherOne" class="com.atguigu.spring.Teacher" p:tid="13" p:tname="王五"></bean>