2.4 通过XML装配bean

前言:
   Spring配置的可选方案 :
    --隐式的bean发现机制和自动装配
    --在Java中进行显式配置
    -- 在XML中进行显式配置
        --构造器注入
        --属性注入

以下内容摘自《Spring实战(第4版)》
2.4.1 创建XML配置规范
    有@Configuration注解的类,而在XML配置中,这意味着要创建 一个XML文件,并且要以<beans>元素为根。
    
    
2.4.2 声明一个简单的<bean>
<bean class = "soundsystem.SgtPeppers" />
     因为没有明确给定ID,所以这个bean将会根据全限定类名来进行命 名。在本例中,bean的ID将会 是“ soundsystem.SgtPeppers#0 ”。
<bean id = "compactDisc" class = "soundsystem.SgtPeppers" />
    单bean声明的一些特征 :
  1.     你不再需要直接负责创建SgtPeppers的实例,在基于JavaConfig的配置中,我们是需要这样做的。当Spring发 现这个<bean>元素时,它将会调用SgtPeppers的默认构造器来创 建bean。在XML配置中,bean的创建显得更加被动,不过,它并没有 JavaConfig那样强大,在JavaConfig配置方式中,你可以通过任何可以想象到的方法来创建bean实例。 
  2.     在这个简单的<bean>声明中,我们将bean的类型以字符串的形式设置在了class属性中。谁能保证设置给class属性的值是真正的类呢?Spring的XML配置并不能从编译期的类型检查中受益。即便它所引用的是实际的类型,如果你重命名 了类,会发生什么呢?借助IDE检查XML的合法性使用能够感知Spring功能的IDE,如 Spring Tool Suite,能够在很大程度上帮助你确保Spring XML配置 的合法性。

2.4.3 借助构造器注入初始化bean
     在Spring XML配置中,只有一种声明bean的方式:使用<bean>元素 并指定class属性。Spring会从这里获取必要的信息来创建bean。
    在XML中声明DI时,会有多种可选的配置方案和风格。具体到 构造器注入,有两种基本的配置方案可供选择:
  •     <constructor-arg>元素 
  •     使用Spring 3.0所引入的c-命名空间
    
<bean id="cdPlayer" class="soundsystem.CDPlayer">
    <constructor-arg ref="compactDisc" />
</bean>
    作为替代的方案,你也可以使用Spring的c-命名空间。c-命名空间是 在Spring 3.0中引入的,它是在XML中更为简洁地描述构造器参数的 方式。要使用它的话,必须要在XML的顶部声明其模式,如下所示:

<bean id = "CDPlayer" class="soundsystem.CDPlayer"
    c:cd-ref="compactDisc" />
</bean>

c                        :    cd                    -ref=                "compactDisc"
c-命名空间前缀        构造器参数名    注入bean引用    要注入的bean的id

    属性名以“c:”开头,也就是命名空间的前缀。接下来就是要装配的构 造器参数名,在此之后是“-ref”,这是一个命名的约定,它会告诉 Spring,正在装配的是一个bean的引用,这个bean的名字 是compactDisc,而不是字面量“compactDisc”。
    引用参数的名称看起来有些怪 异,因为这需要在编译代码的时候,将 调试标志(debug symbol)保存在类代码中。如果你优化构建过程,将调试标志移除掉,那么这种方式可能就无法正常执行了。
    替代的方案是我们使用参数在整个参数列表中的位置信息:
<bean id="cdplayer" class="soundsystem.CDPlayer"
           c:_0-ref="compactDisc" />
    我们已经将引用装配到了其他的bean之中,接下来看一下如何将 字面量值(literal value)装配到构造器之中。

    迄今为止,我们所做的DI通常指的都是 类型的装配——也就是将对象 的引用装配到依赖于它们的其他对象之中——而有时候,我们需要做 的只是用一个字面量值来配置对象。

package soundsystem;
public class BlackDisc implements Compactisc
{
    private String title;
    private String artist;

    public BlankDisc(String title, String artist)
    {
        this.title = title;
        this.artist = artist;
    }
    public void play()
    {
        System.out.println("Playing "+title+" by "+artist);
    }

}

<bean id="compactDisc" class="soundsystem.BlankDisc">
    <constructor-arg value = "Sgt. Pepper's Lonely Hearts Club Band" />
    <constructor-arg value = "The Beatles" />
</bean>
<bean id="compactDisc" class="soundsystem.BlankDisc"
           c:_title="Sgt. Pepper's Lonely Hearts Club Band"
           c:_artist="The Beatles" />
<bean>
<bean id="compactDisc" class="soundsystem.BlankDisc"
           c:_0="Sgt. Pepper's Lonely Hearts Club Band"
           c:_1="The Beatles" />
<bean>

装配集合
package soundsystem.collection;
import java.util.List;
import soundsystem.CompactDisc;

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("Playing " + title + " by " + artist);
        for(String track : tracks)
        {
            System.out.println("-Track: " + track);
        }
    }
}
     在声明bean的时候,我们必须要提供一个 磁道列表
<bean id = "compactDisc" class="soundsystem.BlankDisc">
    <constructor-arg value="Sgr. Pepper's Lonely Hearts Club Band" />
    <constructor-arg value="The Beatles" />
    <constructor-arg><null/></constructor-arg>
</bean>
    <null/>元素所做的事情与你的期望是一样的:将null传递给构造 器。这并不是解决问题的好办法,但在注入期它能正常执行。当调 用play()方法时,你会遇到NullPointerException异常,因此 这并不是理想的方案。
<bean id="compactDisc" class="soundsystem.BlankDisc">
    <constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" />
    <constructor-arg value="The Beatles" />
    <constructor-arg>
        <list>
            <value>Sgt. Pepper's Lonely Hearts Club Band</value>
            <value>With a Little Help from My Friends</value>
            <value>Lucy in the Sky with Diamonds</value>
            <value>Fixing a Hole</value>
        </list>
    </constructor-arg>
</bean>

public Discography(String artist, List<CompactDisc> cds) {...}
<bean id = "beatlesDiscography" class="soundsystem.Discography">
    <constructor-arg value="The Beatles" />
    <constructor-arg>
        <list>
            <ref bean = "sgtPeppers" />
            <ref bean = "whiteAlbum" />
            <ref bean = "hardDaysNight" />
            <ref bean = "revolver" />
            ...
        </list>
    </constructor-arg>
</bean>
<bean id = "beatlesDiscography" class="soundsystem.Discography">
    <constructor-arg value="The Beatles" />
    <constructor-arg>
         <set>
            <ref bean = "sgtPeppers" />
            <ref bean = "whiteAlbum" />
            <ref bean = "hardDaysNight" />
            <ref bean = "revolver" />
            ...
         </set>
    </constructor-arg>
</bean>

     在装配集合方面,<constructor-arg>比c-命名空间的属性更有优 势。目前,使用c-命名空间的属性无法实现装配集合的功能。

2.4.4 设置属性
    Spring XML实现属性注入:
package soundsystem;
import org.springframework.beans.factory.annotation.Autowired;
import soundsystem.CompactDisc;
import soundsystem.MediaPlayer;

public class CDPlayer implements MediaPlayer
{
    private CompactDisc compactDisc;
    
    @Autowired
    public void setCompactDisc(CompactDisc compactDisc)
    {
        this.compactDisc = compactDisc;
    }

    public void play()
    {
        compactDisc.play();
    }
}
<bean id = "cdPlayer" class="soundsystem.CDPlayer">
    <property name = "compactDisc" ref="compactDisc" />
</bean>
     <property>元素为属性的Setter方法所提供的功能与<constructor-arg>元素为构造器所提供的功能是一样的。
    Spring为<constructor-arg>元素提供了c-命名空 间作为替代方案,与之类似,Spring提供了更加简洁的p-命名空间, 作为<property>元素的替代方案。为了启用p-命名空间,必须要在 XML文件中与其他的命名空间一起对其进行声明:
<?xml version="1.0" encoding="UTF-8"?>
    xsi:schemaLocation=" http://www.springframework.org/schema/beans
    ...
</bean>
<bean id = "CDPlayer" class="soundsystem.CDPlayer"
    p:compactDIsc-ref = "compactDisc" />

p:                        compactDIsc    -ref                     = "compactDisc"
p-命名空间前缀    属性名              注入bean引用          注入id
    
将字面量注入到属性中
package soundsystem;
import java.util.List;
import soundsystem.CompactDisc;

public class BlankDisc implements CompactDisc
{
    private String title;
    private String artist;
    private List<String> tracks;

    public void setTitle(String title)
    {
        this.title = title;
    }
    
    public void setArtist(String artist)
    {
        this.artist = artist;
    }

    public void setTracks(List<String> tracks)
    {
        this.tracks = tracks;
    }

    public void play()
    {
        System.out.println("Playing " + title + " by " + artist );
        for (String track : tracks)
        {
            System.out.println("-Track: " + track);
        }
    }
}
<bean id = "compactDisc" class = "soundsystem.BlankDisc">
    <property name = "title" value = "Sgt. Pepper's Lonely Hearts Club Band" />
    <property name = "artist" value = "The Beatles" />
    <property name = "tracks"
        <list>
            <value>Sgt. Pepper's Lonely Hearts Club Band</value>
            <value>With a Little Help from My Friends</value>
            <value>Lucy in the Sky with Diamonds</value>
            <value>Getting Better</value>
            <value>Fixing a Hole</value>
            ...
        </list>
    </property>
</bean>
or
<bean id = "compactDisc" class = "soundsystem.BlankDisc"
    p:title="Sgt. Pepper's Lonely Hearts Club Band"
    p:artist="The Beatles">
<property name = "tracks"
        <list>
            <value>Sgt. Pepper's Lonely Hearts Club Band</value>
            <value>With a Little Help from My Friends</value>
            <value>Lucy in the Sky with Diamonds</value>
            <value>Getting Better</value>
            <value>Fixing a Hole</value>
            ...
        </list>
    </property>
</bean>
    我们 不能使用p-命名空间来装配集合,没有便利的方式使用p-命名空间来指定一个值(或bean引用)的列表。但是,我 们可以使用 Spring util- 命名空间中的一些功能来简 化BlankDiscbean。
    在XML中声明util-命名空间及其模式:
<util:list id="trackList">
    <value>Sgt. Pepper's Lonely Hearts Club Band</value>
    <value>With a Little Help from My Friends</value>
    <value>Lucy in the Sky with Diamonds</value>
    <value>Getting Better</value>
    <value>Fixing a Hole</value>
</utli:list>
<bean id="compactDisc"
    class="soundsystem.BlankDisc
    p:title="Sgt. Pepper's Lonely Hearts Club Band"
    p:artist="The Beatles"
     p:tracks-ref="trackList" />


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








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值