您的位置:首页 > 编程语言 > Java开发

Spring学习笔记之通过XML装配Bean的一些细节

2016-10-20 17:13 681 查看

一、c命名空间

通过构造器注入Bean的时候通常需要使用到<constructor-arg>元素,作为替代的方案,可以使用Spring的c-命名空间。c-命名空间是在Spring 3.0中加入的,它是在XML中更为简洁地描述构造器参数的方式。要使用c-命名空间,必须要在XML的顶部声明其模式,如下所示:

<?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-命名空间和模式声明后,就可以使用它来声明构造器参数了,如下所示:

<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即为构造器参数的名称,这种方式对于后期代码的重构是非常不友好的,那么为了解决这个问题,可以使用参数的索引来替代参数名称,如下所示:
<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" />

当然如果构造器只有一个参数,可以连索引一起略去:
<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类的代码如下:

package cn.javacodes.spring.beans.soundsystem.collections;
import cn.javacodes.spring.beans.soundsystem.CompactDisc;
import java.util.List;
/**
* Created by Eric on 2016/10/16.
*/
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,当然,你可以给它传递为空值:
<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。

我们有很多种解决方案,首先,可以使用<list>元素将其声明为一个列表:

<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>


当然,也可以使用<ref>来替代<value>达到引用其它bean的目的,再次不做赘述。

在我们的例子中构造器参数类型为List,因此使用<list>元素进行注入是合情合理的,尽管如此,我们仍然可以使用<set>元素来进行注入:

<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>


<set>和<list>元素的区别并不大,其中最重要的区别在于Spring创建要装配的集合时,所创建的是Set还是List。如果是Set的话,所有重复的值都会被忽略掉,并且存放的顺序也不会得到保证,这个相信大家对Set和List的区别都有明确的认识。不过无论哪种情况下,<set>和<list>都可以用来装配List、Set甚至数组。

(二)、装配Map

我们将上面的BlankDisc稍作改动,将原有的List改为Map:

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的方式如下:
<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>


当然<key>和<value>元素可以分别用<key-ref>和<value-ref>元素替代用于引用其它Bean。

(三)、装配Properties

Properties与Map非常类似,不过区别主要在于Map的key和Value可以是任意类型的对象,而Properties要求key和value必须都是String类型,而很多场景下我们的key和value的确都是String类型,比如数据库连接信息的配置。
为了演示Properties的相关配置,我们创建一个类DataSource:

package cn.javacodes.spring.beans.properties;
import java.util.Properties;
/**
* Created by Eric on 2016/10/16.
*/
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配置如下:
<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的属性时需要使用<property>元素,为了简化这种方式,与c命名空间一样,Spring为我们提供了p命名空间。为了使用p-命名空间,必须在xml顶部进行声明:

<?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-命名空间了,使用方法如下:
<bean id="cdPlayer" class="cn.javacodes.spring.beans.soundsystem.CDPlayer"
p:cd-ref="compactDisc"/>


属性的名称以-ref结尾的,代表Spring要进行装配的是bean的引用而不是字面值(String)。

四、util命名空间

p-命名空间和c-命名空间都不能对集合类型进行装配,不过我们可以使用util命名空间来简化对集合的装配,声明如下:

<?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命名空间了,例如:
<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轻松引用,如下所示:
<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,其中包含值或引用
 

 

 

本文为博主独立博客(https://javacodes.cn)同步发表,转载请注明出处。
查看原文:https://javacodes.cn/333.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: