用来记录一些原创性的总结
在通过构造方法或set
方法给bean
注入关联项时通常是通过constructor-arg
元素和property
元素来定义的。在有了p
命名空间和c
命名空间时我们可以简单的把它们当做bean
的一个属性来进行定义。
使用p
命名空间时需要先声明使用对应的命名空间,即在beans
元素上加入xmlns:p="http://www.springframework.org/schema/p"
。下面先来看一个示例。
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="world" class="com.app.World"/>
<!-- 通过set方法注入的传统的bean定义 -->
<bean id="hello1" class="com.app.Hello">
<property name="p1" value="v1"/>
<property name="p2" value="v2"/>
<property name="world" ref="world"/>
</bean>
<!-- 通过set方法注入的使用p命名空间的bean定义 -->
<bean id="hello2" class="com.app.Hello" p:p1="v1" p:p2="v2" p:world-ref="world"/>
</beans>
在上面示例中,id
为hello1
的bean
是传统的bean
定义,而id
为hello2
的bean
是基于p
命名空间的bean
定义。当传统的property
元素定义的value
是基础数据类型时,我们可以直接把property
元素对应的name
加上p
命名空间的前缀作为bean
的一个属性进行定义,对应的值就是原property
元素对应的value
。如上述示例中name
为“p1”
的property
使用p
命名空间后就变成了“p:p1”
;当传统的property
元素定义的是对其它bean
的关联时,我们可以直接把property
元素对应的name
加上“-ref”
,再加上p
命名空间的前缀作为bean
的一个属性进行定义,对应的值为原property
元素对应的ref
值,如上述示例中name
为“world”
的property
就是定义了对其它bean
的关联,使用p
命名空间后就变成了“p:world-ref”
。这里有一点需要注意的地方就是property
对应的是set
方法,而不是对应的属性,如name
为“world”
的property
实际上对应的是setWorld()
方法,这个时候不管对应的bean
是否真存在名为world
的属性;另一点需要注意的地方是使用p
命名空间时要注意以“-ref”
结尾的property
,这会导致Spring
以其前部分作为property
,因为“-ref”
会被Spring
作为关联的关键字。
c
命名空间的用法和p
命名空间类似,其对应于constructor-arg
,即可以将constructor-arg
元素替换为bean
的一个以c
命名空间前缀开始的属性。使用c
命名空间之前也需要通过xmlns:c=”http://www.springframework.org/schema/c”
进行声明。
<?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="world" class="com.app.World"/>
<!-- 传统的使用constructor-arg通过构造方法注入的bean定义 -->
<bean id="hello1" class="com.app.Hello">
<constructor-arg index="0" value="arg1"/>
<constructor-arg index="1" value="2"/><!-- arg2 -->
<constructor-arg index="2" ref="world"/><!-- arg3 -->
</bean>
<!-- 使用c命名空间通过构造方法注入的bean定义 -->
<bean id="hello2" class="com.app.Hello" c:arg1="c_arg1" c:arg2="2" c:arg3-ref="world"/>
</beans>
如上所示,c
命名空间的用法和p
命名空间的用法类似。对于通过构造方法注入原始类型的对象可以把对应的构造参数名称加上c
命名空间的前缀作为bean
的一个属性进行定义,对应的值即是构造参数的值;如果通过构造参数注入的是其它bean
的一个引用,则可将该构造参数名称加上“-ref”
,再加上c
命名空间的前缀作为该bean
的一个属性进行定义,对应的值为所关联bean
的id
或name
,如上述示例中的“c:arg3-ref”
。
需要注意的是直接把构造参数名称加上c
命名空间的前缀作为bean
的一个属性定义来替代对应的constructor-arg
只对以debug
方式编译的class
有效,因为对于非debug
方式编译的class
文件Spring
将无法获取到对应构造方法的参数名。对于这种情况我们可以直接使用构造方法参数的索引加上下划线“_”
前缀来代替对应的参数名,索引是从0开始的,如上面的示例以索引来代替时将是如下这个样子。
<?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="world" class="com.app.World"/>
<!-- 传统的使用constructor-arg通过构造方法注入的bean定义 -->
<bean id="hello1" class="com.app.Hello">
<constructor-arg index="0" value="arg1"/>
<constructor-arg index="1" value="2"/><!-- arg2 -->
<constructor-arg index="2" ref="world"/><!-- arg3 -->
</bean>
<!-- 使用c命名空间并且是使用构造参数的索引作为属性来通过构造方法注入的bean定义 -->
<bean id="hello2" class="com.app.Hello" c:_0="c_arg1" c:_1="2" c:_2-ref="world"/>
</beans>
(注:本文是基于Spring4.1.0所写)