1 包含 XML 特殊符号
在 Spring 配置文件中,可以使用字面值来提供配置的值。如果配置的值包含 XML 特殊符号,那么可以在属性值外添加一个 XML 特殊处理标签 <![CDATA[]]>
,作用是让 XML 解析器将标签中的字符串当作普通文本来对待。
XML 中有 5 个特殊字符,有两种方式可以对这些字符进行特别处理。
- 使用标签
<![CDATA[]]>
,来包裹特殊字符。 - 使用 XML 转义序列来表示这些字符。
特殊字符 | 转义序列 |
---|---|
< |
< |
> |
> |
& |
& |
" |
" |
' |
' |
注意: Spring 不会忽略标签内容字符串的前后空格。
2 引用其他 Bean
Spring IoC 容器中定义的 Bean 可以相互引用。
<bean id="author" class="net.deniro.spring4.bean.Author">
<property name="name" value="deniro"/>
</bean>
<bean id="book" class="net.deniro.spring4.bean.Book">
<property name="author">
<ref bean="author"></ref>
</property>
</bean>
<ref>
元素可以通过以下 3 个属性引用容器中的其他 Bean:
属性 | 说明 |
---|---|
bean | 可以引用同一容器或父容器中的 Bean。 |
local | 只能引用同一个配置文件中定义的 Bean,会自动检查合法性 。 |
parent | 引用父容器中的 Bean ,如 <ref parent="xxx"> ,说明这个 Bean 的父容器是 xxx。 |
父容器配置:
<!-- 父容器-->
<bean id="author" class="net.deniro.spring4.bean.Author">
<property name="name" value="deniroFather"/>
</bean>
子容器配置:
<bean id="author" class="net.deniro.spring4.bean.Author">
<property name="name" value="deniro"/>
</bean>
<bean id="book" class="net.deniro.spring4.bean.Book">
<property name="author">
<ref parent="author"/>
</property>
</bean>
子容器配置中存在与父容器相同的 bean id(这里是 author),在 book 中,我们使用的是 <ref parent="author"/>
,所以它引用的是父容器的 Bean。
ApplicationContext parent = new ClassPathXmlApplicationContext
(new String[]{"parent.xml"});
ApplicationContext context = new ClassPathXmlApplicationContext(new
String[]{"beans.xml"},
parent);////把父容器上下文作为参数传入
3 内部 Bean
如果某个 Bean 只在一个确定的 Bean 中被引用,那么它可以以内部 Bean 的形式被引用:
<bean id="book" class="net.deniro.spring4.bean.Book">
<property name="author">
<bean class="net.deniro.spring4.bean.Author">
<property name="name" value="deniro"/>
</bean>
</property>
</bean>
内部 Bean 与 Java 的匿名内部类类似,它没有名字,所以只能在声明处注入实例。
注意:内部 Bean 的 id、name 与 scope 属性配置是无效的,scope 属性默认为 prototype,无法更改。
4 null 值
有时候需要注入一个 null 值,那么可以使用 <null/>
:
<bean id="book2" class="net.deniro.spring4.bean.Book">
<property name="name"><null/></property>
</bean>
5 级联属性
Spring 支持级联属性。假设我们希望在 book 中直接注入 author 的名字:
<bean id="book3" class="net.deniro.spring4.bean.Book">
<property name="author.name" value="deniro"/>
</bean>
还需要初始化 Book 类的 author 属性:
private Author author=new Author();
如果没有初始化 author 属性,Spring 将抛出 NullValueInNestedPathException 异常。
只要配置的 Bean 拥有对应于级联属性的类结构,就可以配置任意层级的级联属性。
6 集合类型
Spring 为 List、Set、Map 与 Properties 提供了专属的配置标签。
6.1 List
<bean id="book4" class="net.deniro.spring4.bean.Book">
<property name="labels">
<list>
<value>历史</value>
<value>传记</value>
</list>
</property>
</bean>
为 Book 添加 labels 属性:
/**
* 标签
*/
private List<String> labels=new ArrayList<String>();
public List<String> getLabels() {
return labels;
}
public void setLabels(List<String> labels) {
this.labels = labels;
}
list 属性既可以通过 <value>
注入字符串,也可以使用 <ref>
注入容器中的其他 Bean。
注意: 一个属性类型,如果可以通过字符串的字面值进行配置,那么该类型所对应的数组类型(如:String[]
、int[]
)也可以采用 <list>
的方式进行配置。
6.2 Set
Set 配置与 List 配置相似:
<bean id="book5" class="net.deniro.spring4.bean.Book">
<property name="labelSet">
<set>
<value>历史</value>
<value>传记</value>
</set>
</property>
</bean>
labelSet 在 Book 中必须是 Set 类型:
private Set<String> labelSet=new HashSet<String>();
public Set<String> getLabelSet() {
return labelSet;
}
public void setLabelSet(Set<String> labelSet) {
this.labelSet = labelSet;
}
6.3 Map
我们为 Book 添加版本说明:
/**
* 版本
*/
private Map<String,String> versions=new HashMap();
public Map<String, String> getVersions() {
return versions;
}
public void setVersions(Map<String, String> versions) {
this.versions = versions;
}
配置:
<bean id="book6" class="net.deniro.spring4.bean.Book">
<property name="versions">
<map>
<entry>
<key><value>1</value></key>
<value>2017-1</value>
</entry>
<entry>
<key><value>2</value></key>
<value>2017-2</value>
</entry>
</map>
</property>
</bean>
如果某个 Map 元素的键与值是对象,那么可以这样配置:
<entry>
<key><ref bean="keyBean"/></key>
<ref bean="valueBean"/>
</entry>
6.4 Properties
Map 元素的键与值可以是任意类型对象,而 Properties 元素的键与值只能是字符串,所以 Properties 元素其实是 Map 元素的特殊情况。
我们为 Author 添加地址属性列:
/**
* 地址
*/
private Properties addresses=new Properties();
public Properties getAddresses() {
return addresses;
}
public void setAddresses(Properties addresses) {
this.addresses = addresses;
}
配置:
<bean id="author1" class="net.deniro.spring4.bean.Author">
<property name="addresses">
<props>
<prop key="home">北京</prop>
<prop key="work">杭州</prop>
</props>
</property>
</bean>
因为 Properties 元素的键值只能是字符串,所以配置上比 Map 来的简单。
6.5 强类型集合
强类型指的是包装类型,如果 POJO 中,存在强类型的集合,Spring 也可以注入:
/**
* 收入
*/
private Map<String,Double> income=new HashMap<String, Double>();
public Map<String, Double> getIncome() {
return income;
}
public void setIncome(Map<String, Double> income) {
this.income = income;
}
配置:
<bean id="author2" class="net.deniro.spring4.bean.Author">
<property name="income">
<map>
<entry>
<key>
<value>第一季度</value>
</key>
<value>20000.00</value>
</entry>
<entry>
<key>
<value>第二季度</value>
</key>
<value>30000.00</value>
</entry>
</map>
</property>
</bean>
Spring 容器在注入强类型集合时,会判断元素的类型,把相应的配置值转换为对应的数据类型。
6.6 合并集合
Spring 允许子 <bean>
继承 父 <bean>
中同名属性的集合元素。
<!-- 父 Bean -->
<bean id="fatherBook" class="net.deniro.spring4.bean.Book" abstract="true">
<property name="labels">
<list>
<value>历史</value>
<value>地理</value>
</list>
</property>
</bean>
<!-- 子 Bean -->
<bean id="childBook" class="net.deniro.spring4.bean.Book" parent="fatherBook">
<property name="labels">
<list merge="true">
<value>天文</value>
<value>数学</value>
</list>
</property>
</bean>
配置中把父 bean 的 abstract 属性设置为 true,表示是一个抽象的 Bean;然后在子 Bean的 parent 属性中指定父 bean 的 id;最后把集合标签的 merge 设置为 true,表示合并。
6.7 集合类型的 Bean
上面所说的都是在一个 Bean 中配置集合类型的属性。如果需要一个集合类型的 Bean,则需要使用 util 命名空间。首先在 Spring 的配置文件头中引入 util 命名空间:
<?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: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-4.0.xsd
">
配置 List:
<util:list id="type" list-class="java.util.LinkedList">
<value>人文</value>
<value>科技</value>
</util:list>
配置 Set:
<util:set id="type2" set-class="java.util.HashSet">
<value>人文</value>
<value>科技</value>
</util:set>
配置 Map:
<util:map id="config" map-class="java.util.HashMap">
<entry key="账号" value="admin"/>
<entry key="密码" value="123456"/>
</util:map>
提示:
- xxx-class 属性为可选项。
-
<util:list>
与<util:set>
拥有 value-type 属性,可以指定集合中的值类型。 -
<util:map>
拥有 key-type 和 value-type 属性,可以指定 Map 的键或值的类型。