7.11.2 使用c命名空间简化配置

7.11.2 使用c:命名空间简化配置

p:命名空间主要用于简化设值注入,而c:命名空间则用于简化构造注入。

假设有如下的持久化类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.crazyit.app.service.impl;

import org.crazyit.app.service.*;

public class Chinese implements Person
{
private Axe axe;
private int age;
// 构造注入所需的带参数的构造器
public Chinese(Axe axe, int age)
{
this.axe = axe;
this.age = age;
}
// 实现Person接口的useAxe()方法
public void useAxe()
{
// 调用axe的chop()方法
// 表明Person对象依赖于axe对象
System.out.println(axe.chop());
System.out.println("age成员变量的值:" + age);
}
}

上面Chinese类的构造器需要两个参数,传统配置是在<bean>元素中添加两个<constructor-arg>子元素来代表构造器参数;导入c:命名空间之后,可以直接使用属性来配置构造器参数

c:属性的使用格式

使用c:指定构造器参数的格式为:

  • c:构造器参数名="值"
  • c:构造器参数名-ref=其他Bean的id"

程序示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\c_namespace
└─src\
├─beans.xml
├─lee\
│ └─BeanTest.java
└─org\
└─crazyit\
└─app\
└─service\
├─Axe.java
├─impl\
│ ├─Chinese.java
│ ├─SteelAxe.java
│ └─StoneAxe.java
└─Person.java

beans.xml

本应用的配置文件beans.xml如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置chinese实例,其实现类是Chinese -->
<bean id="chinese" class="org.crazyit.app.service.impl.Chinese"
c:axe-ref="steelAxe" c:age="29"/>
<!-- 配置chinese实例,其实现类是Chinese -->
<bean id="chinese2" class="org.crazyit.app.service.impl.Chinese"
c:_0-ref="steelAxe" c:_1="29"/>
<!-- 配置stoneAxe实例,其实现类是StoneAxe -->
<bean id="stoneAxe" class="org.crazyit.app.service.impl.StoneAxe"/>
<!-- 配置steelAxe实例,其实现类是SteelAxe -->
<bean id="steelAxe" class="org.crazyit.app.service.impl.SteelAxe"/>
</beans>

引入c:名字空间

配置文件中<beans>元素上的xmlns:c属性:

1
xmlns:c="http://www.springframework.org/schema/c"

用于导入XML Schema里的c:命名空间

使用 c:构造器参数名 来设置构造器参数

配置文件的如下代码

1
2
3
<!-- 配置chinese实例,其实现类是Chinese -->
<bean id="chinese" class="org.crazyit.app.service.impl.Chinese"
c:axe-ref="steelAxe" c:age="29"/>

则直接使用属性配置了axeage两个构造器参数,由于axe构造器参数需要引用容器中另一个已存在的Bean实例,故在axe后增加了"ref"后缀,这个后缀指定该值不是一个具体的值,而是对另外个Bean的引用。

使用 c:_索引 来设置构造器参数

上面配置方式是在c:后使用构造器参数名来指定构造器参数, Spring还支持一种通过索引来配置构造器参数的方式。上面的Bean也可改写为如下形式:

1
2
<bean id="chinese" class="org.crazyit.app.service.impl.Chinese"
c:_0-ref="steelAxe" c:_1="29/>

c:_0-ref属性指定使用容器中已有的idsteelAxe这个Bean作为第一个构造器参数,
c:_1="29"则指定使用29作为第二个构造器参数。

在这种方式下,c:_N中的N代表第几个构造器参数(N从0开始)。

使用constructor-arg元素要按构造器参数的顺序注入

前面介绍介绍构造注入时,通常总是根据构造参数的顺序来注入,比如说希望调用Person类的构造器Person(String,int),则在XML中配置时需要将String构造参数对应的<constructor-arg>元素放在第1位,将int构造参数对应的<constructor-arg>元素放在第2位

如何根据构造器参数的名称来注入

如果希望根据构造参数的名称来配置构造注入,则可使用java.beans包的@ConstructorProperties注解

程序示例

1
2
3
4
5
6
7
8
9
10
E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\ConstructorProperties
└─src\
├─beans.xml
├─lee\
│ └─BeanTest.java
└─org\
└─crazyit\
└─app\
└─service\
└─Person.java

例如如下代码使用@ConstructorProperties注解为构造参数指定参数名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.crazyit.app.service;
import java.beans.ConstructorProperties;
public class Person
{
private String name;
private int age;
@ConstructorProperties({"personName", "age"})
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
// 此处省略getter和setter方法,请自己补上
@Override
public String toString()
{
return "Person[name=" + name + ",age=" + this.age + "]";
}
}

上面程序中的@ConstructorProperties({"personName", "age"})注解,指定Person构造器的两个构造参数的名字为:personNameage(@ConstructorProperties注解指定的名字并不需要与构造参数实际的名字相同)。
接下来就可在配置文件beans.xml中通过构造参数名来执行构造注入的配置了,例如如下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
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">
<!-- 使用ConstructorProperties配置了构造参数名之后,
接下来即可通过构造参数名来配置构造注入 -->
<bean id="person" class="org.crazyit.app.service.Person">
<constructor-arg name="age" value="500" />
<constructor-arg name="personName" value="孙悟空" />
</bean>
</beans>

当然也可使用c:命名空间进行简化配置,上面配置可改为如下形式。

1
2
<bean id="person" class="org.crazyit.app.service.Person"
c:age="500" c:personName="孙悟空" />