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

一、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,其中包含值或引用

 

 

 

若未注明来源即为原创文章,本站使用“署名·非商业用途·保持一致”版权协议
转载请注明:
转载自老H博客
本文链接地址: Spring学习笔记之通过XML装配Bean的一些细节

共有 0 条评论

Top