一、c 命名空间 通过构造器注入 Bean 的时候通常需要使用到元素,作为替代的方案,可以使用 Spring 的 c - 命名空间。c - 命名空间是在 Spring 3.0 中加入的,它是在 XML 中更为简洁地描述构造器参数的方式。要使用 c - 命名空间,必须要在 XML 的顶部声明其模式,如下所示:
1 2 3 4 5 6 <?xml version="1.0" encoding="UTF-8"?> <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" > </beans >
在 c - 命名空间和模式声明后,就可以使用它来声明构造器参数了,如下所示:
1 2 3 4 <bean id ="compactDisc" class ="cn.javacodes.spring.beans.soundsystem.Transfer" > </bean > <bean id ="cdPlayer" class ="cn.javacodes.spring.beans.soundsystem.CDPlayer" c:cd-ref ="compactDisc" />
可以看到上面的方式也有一些问题,c:cd-ref 中的 cd 即为构造器参数的名称,这种方式对于后期代码的重构是非常不友好的,那么为了解决这个问题,可以使用参数的索引来替代参数名称,如下所示:
1 2 3 <bean id ="compactDisc" class ="cn.javacodes.spring.beans.soundsystem.Transfer" > </bean > <bean id ="cdPlayer" class ="cn.javacodes.spring.beans.soundsystem.CDPlayer" c:_0-ref ="compactDisc" />
当然如果构造器只有一个参数,可以连索引一起略去:
1 2 3 <bean id ="compactDisc" class ="cn.javacodes.spring.beans.soundsystem.Transfer" > </bean > <bean id ="cdPlayer" class ="cn.javacodes.spring.beans.soundsystem.CDPlayer" c:_-ref ="compactDisc" />
不过在我的测试中,这种方式在 idea 中会报错。
二、装配集合 (一)装配 List 和 Set BlankDisc 类的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package cn.javacodes.spring.beans.soundsystem.collections;import cn.javacodes.spring.beans.soundsystem.CompactDisc;import java.util.List;public class BlankDisc implements CompactDisc { private String title; private String artist; private List<String> tracks; public BlankDisc (String title, String artist, List<String> tracks) { this .title = title; this .artist = artist; this .tracks = tracks; } public void play () { System.out.println("正在播放" + artist + "的专辑:" + title); for (String track : tracks) { System.out.println("-Track:" + track); } } }
在 Spring 中配置这个类的 bean 时需要提供一个 list,当然,你可以给它传递为空值:
1 2 3 4 5 <bean id ="compactDisc" class ="cn.javacodes.spring.beans.soundsystem.collections.BlankDisc" > <constructor-arg value ="Transfer" > </constructor-arg > <constructor-arg value ="周传雄/小刚" > </constructor-arg > <constructor-arg > <null /> </constructor-arg > </bean >
不过如果传递 null 的话,当调用 play () 方法时,必然会产生 NullPointerException 异常,通常情况下,我们更多的给它装配一个 List。
我们有很多种解决方案,首先,可以使用元素将其声明为一个列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <bean id ="compactDisc" class ="cn.javacodes.spring.beans.soundsystem.collections.BlankDisc" > <constructor-arg value ="Transfer" > </constructor-arg > <constructor-arg value ="周传雄/小刚" > </constructor-arg > <constructor-arg > <list > <value > 忘记</value > <value > 出卖</value > <value > 寂寞轰炸</value > <value > 游戏爱情</value > <value > 心结</value > <value > 记事本</value > <value > 啤酒泡泡</value > <value > 黄昏</value > <value > 末班车</value > <value > 心血来潮</value > <value > 时间</value > </list > </constructor-arg > </bean >
当然,也可以使用[来替代]达到引用其它 bean 的目的,再次不做赘述。
在我们的例子中构造器参数类型为 List,因此使用元素进行注入是合情合理的,尽管如此,我们仍然可以使用元素来进行注入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <bean id ="compactDisc" class ="cn.javacodes.spring.beans.soundsystem.collections.BlankDisc" > <constructor-arg value ="Transfer" > </constructor-arg > <constructor-arg value ="周传雄/小刚" > </constructor-arg > <constructor-arg > <set > <value > 忘记</value > <value > 出卖</value > <value > 寂寞轰炸</value > <value > 游戏爱情</value > <value > 心结</value > <value > 记事本</value > <value > 啤酒泡泡</value > <value > 黄昏</value > <value > 末班车</value > <value > 心血来潮</value > <value > 时间</value > </set > </constructor-arg > </bean >
和元素的区别并不大,其中最重要的区别在于 Spring 创建要装配的集合时,所创建的是 Set 还是 List。如果是 Set 的话,所有重复的值都会被忽略掉,并且存放的顺序也不会得到保证,这个相信大家对 Set 和 List 的区别都有明确的认识。不过无论哪种情况下,和都可以用来装配 List、Set 甚至数组。
(二)、装配 Map 我们将上面的 BlankDisc 稍作改动,将原有的 List 改为 Map:
1 2 3 4 5 6 7 8 private String title;private String artist;private Map<String,String> tracks;public BlankDisc (String title, String artist, Map<String, String> tracks) { this .title = title; this .artist = artist; this .tracks = tracks; }
装配 Map 的方式如下:
1 2 3 4 5 6 7 8 9 10 11 <bean id ="compactDisc" class ="cn.javacodes.spring.beans.soundsystem.collections.BlankDisc" > <constructor-arg value ="Transfer" > </constructor-arg > <constructor-arg value ="周传雄/小刚" > </constructor-arg > <constructor-arg > <map > <entry key ="忘记" value ="5:12" /> <entry key ="出卖" value ="4:54" /> <entry …… </map> </constructor-arg > </bean >
当然和元素可以分别用和元素替代用于引用其它 Bean。
(三)、装配 Properties Properties 与 Map 非常类似,不过区别主要在于 Map 的 key 和 Value 可以是任意类型的对象,而 Properties 要求 key 和 value 必须都是 String 类型,而很多场景下我们的 key 和 value 的确都是 String 类型,比如数据库连接信息的配置。
为了演示 Properties 的相关配置,我们创建一个类 DataSource:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package cn.javacodes.spring.beans.properties;import java.util.Properties;public class DataSource { private Properties properties; public DataSource (Properties properties) { this .properties = properties; } public Properties getProperties () { return properties; } public void setProperties (Properties properties) { this .properties = properties; } }
在 Spring XML 配置如下:
1 2 3 4 5 6 7 8 9 10 <bean id ="dataSource" class ="cn.javacodes.spring.beans.properties.DataSource" > <constructor-arg > <props > <prop key ="user" > root</prop > <prop key ="password" > 123456</prop > <prop key ="url" > jdbc:mysql:///test</prop > <prop key ="driver" > com.mysql.jdbc.Driver</prop > </props > </constructor-arg > </bean >
三、p 命名空间 我们知道配置 bean 的属性时需要使用元素,为了简化这种方式,与 c 命名空间一样,Spring 为我们提供了 p 命名空间。为了使用 p - 命名空间,必须在 xml 顶部进行声明:
1 2 3 4 5 6 7 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns ="http://www.springframework.org/schema/beans" 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" > …… </beans >
然后就可以使用 p - 命名空间了,使用方法如下:
1 2 <bean id ="cdPlayer" class ="cn.javacodes.spring.beans.soundsystem.CDPlayer" p:cd-ref ="compactDisc" />
属性的名称以 - ref 结尾的,代表 Spring 要进行装配的是 bean 的引用而不是字面值(String)。
四、util 命名空间 p - 命名空间和 c - 命名空间都不能对集合类型进行装配,不过我们可以使用 util 命名空间来简化对集合的装配,声明如下:
1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns ="http://www.springframework.org/schema/beans" xmlns:p ="http://www.springframework.org/schema/p" xmlns:c ="http://www.springframework.org/schema/c" 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" > </beans >
现在就可以使用 util 命名空间了,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 <util:list id ="trackList" > <value > 忘记</value > <value > 出卖</value > <value > 寂寞轰炸</value > <value > 游戏爱情</value > <value > 心结</value > <value > 记事本</value > <value > 啤酒泡泡</value > <value > 黄昏</value > <value > 末班车</value > <value > 心血来潮</value > <value > 时间</value > </util:list >
然后就可以像引用其它 Bean 一样将 list 轻松引用,如下所示:
1 2 <bean id ="compactDisc" class ="cn.javacodes.spring.beans.soundsystem.collections.BlankDisc" c:title ="Transfer" c:artist ="周传雄/小刚" c:tracks-ref ="trackList" />
util:list 只是 util - 命名空间提供的众多元素之一,下表列出了 util - 命名空间提供的所有元素:
元素
描述
util:constant
引用某个类型的 public static 域,并墙漆暴露为 bean
util:list
创建一个 java.util.List 类型的 bean,其中包含值或引用
util:map
创建一个 java.util.Map 类型的 bean,其中包含值或引用
util:properties
创建一个 java.util.Properties 类型的 bean
util:property-path
引用一个 bean 的属性(或内嵌属性),并将其暴露为 bean
util:set
创建一个 java.util.set 类型的 bean,其中包含值或引用