Spring基础—装配bean(二)

2 注入bean属性

上文中讲的是构造器注入的方式,现在讲如何注入bean的属性。bean的属性是什么,其实就是一个类对应的数据成员。当一个类定义了一个数据成员以后,一般就会有对应于这个数据成员的setXXX()和getXXX()方法,而Spring注入bean属性就是通过setter注入的。

2.1 注入简单的值和引用

仍然先举一个例子:用Spring配置一个bean,给这个bean注入属性,这个bean指向的类里有一个方法,用来描述一下动作:java学习者在写30篇博客同时还在听歌。

首先还是先写一个主体类:SongJavaer2.java

package com.springinaction.springidol;

/** * 听歌的编程者 * @author 白鑫 * @date 2016-1-6下午11:01:14 */
public class SongJavaer2 implements Coder{
    private int blogNum;
    public void setBlogNum(int blogNum) {
        this.blogNum = blogNum;
    }

    private Song song;
    public void setSong(Song song) {
        this.song = song;
    }

    public void perform() {
        System.out.println("Trigl is writing " +  blogNum + " blogs.");
        System.out.println("While listening...");
        song.play();
    }
}

继承的接口Coder.java见上面,这个类定义了两个数据成员:int类型的blogNum和类Song的对象song,下面我们将实现用Spring将这两个属性注入。

在XML文件中配置bean

    <bean id="songJavaer2" class="com.springinaction.springidol.SongJavaer2">
        <property name="blogNum" value="30" />
        <property name="song" ref="songJay" />
    </bean>
    <bean id="songJay" class="com.springinaction.springidol.SongJay" />

可以看到,Spring注入属性是通过<bean>元素的<property>属性来实现的,其中name的值对应所注入的类的数据成员,也即bean的属性。当注入普通的原始数据成员类型如整型、字符型的时候,是用value来赋值的;当注入另一个bean的引用的时候,是用ref来赋值的。

main方法加载上下文环境进行测试

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
        "com/springinaction/springidol/spring-idol.xml");
        Coder coder = (Coder) ctx.getBean("songJavaer2");
        coder.perform();
    }

控制台输出结果是:

Trigl is writing 30 blogs.
While listening...
一盏离愁孤灯伫立在窗口
我在门后假装你人还没走
旧地如重游月圆更寂寞
夜半清醒的烛火不忍苛责我
一壶漂泊浪迹天涯难入喉
你走之后酒暖回忆思念瘦
水向东流时间怎么偷
花开就一次成熟我却错过
谁在用琵琶弹奏一曲东风破
岁月在墙上剥落看见小时候
犹记得那年我们都还很年幼
而如今琴声幽幽我的等候你没听过
谁在用琵琶弹奏一曲东风破
枫叶将故事染色结局我看透
篱笆外的古道我牵着你走过
荒烟漫草的年头就连分手都很沉默

2.2 注入内部bean

一般来说,我们注入属性时引用的bean还可以被其他bean所引用,但是如果我们想单独霸占一个bean,即仅被某一个bean所使用,其他bean无法使用,那该怎么办呢?很简单,直接在<property>属性里面写一个<bean>元素即可,但是注意,<bean>元素里面只有class没有id,当然你也可以写一个id,但是这样完全没有必要,因为这个bean不会被其他bean引用,所以定义了id也不可能用到,例子如下:

    <bean id="songJavaer2" class="com.springinaction.springidol.SongJavaer2">
        <property name="song">
            <bean class="org.springinaction.springidol.SongJavaer" />
        </property>
    </bean>

而且在构造器注入时也可以这样注入内部bean,如下:

    <bean id="songJavaer" class="com.springinaction.springidol.SongJavaer">
        <constructor-arg>
            <bean class="org.springinaction.springidol.SongJavaer" />
        </constructor-arg>
    </bean>

2.3 注入集合

上面我们讲了注入简单的值和引用的bean,还有一种复杂的情况就是需要注入这些值或者bean的集合。一般在类中可以选择作为数据成员的集合性的类有以下几种:数组、java.util.Collection、java.util.Set、java.util.List、java.util.Map、java.util.Properties,对应于Spring在XML文件中配置bean的元素有<list><set><map><props>,具体差别见下表:

集合配置元素 可注入的集合类 配置说明
<list> 数组、Collection、Set、List 允许重复的集合
<set> 数组、Collection、Set、List 不允许重复的集合
<map> Map 对应的key和value可以取任何类型
<props> Properties 对应的key和value只可以取String类型

细节知识仍然是通过例子来讲解:用Spring配置一个bean,给这个bean注入属性,这个属性要求是集合类,这个bean指向的类里有一个方法,用来描述一下动作:java学习者在听一组歌曲。

首先写主体类SongJavaer3.java

package com.springinaction.springidol;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/** * 唱歌的编程者 * @author 白鑫 * @date 2016-1-6下午11:29:49 */
public class SongJavaer3 implements Coder {
    //Collection在XML中对应于<list>或者<set>
    private Collection<Song> songCollection;
    public void setSongCollection(Collection<Song> songCollection) {
        this.songCollection = songCollection;
    }

    //List在XML中对应于<list>或者<set>
    private List<Song> songList;
    public void setSongList(List<Song> songList) {
        this.songList = songList;
    }

    //Map在XML中对应于<map>
    private Map<String,Song> songMap;
    public void setSongMap(Map<String,Song> songMap) {
        this.songMap = songMap;
    }

    //Properties在XML中对应于<props>
    private Properties songProperties;
    public void setSongProperties(Properties songProperties) {
        this.songProperties = songProperties;
    }

    public void perform() {
        System.out.println("Trigl一边写Java博客一边听歌");
        System.out.println("————————我是可爱的分割线————————");
        System.out.println("播放songCollection中的歌曲......");
        System.out.println();
        for(Song song : songCollection) {
            song.play();
        }
        System.out.println("————————我是可爱的分割线————————");
        System.out.println("播放songList中的歌曲......");
        System.out.println();
        for(Song song : songList) {
            song.play();
        }
        System.out.println("————————我是可爱的分割线————————");
        System.out.println("播放songMap中的歌曲......");
        System.out.println();
        for(String key : songMap.keySet()) {
            System.out.print(key + ":");
            Song song = songMap.get(key);
            song.play();
        }
        System.out.println("————————我是可爱的分割线————————");
        System.out.println("播放songProperties中的歌曲......");
        System.out.println();
        for(Iterator it = songProperties.keySet().iterator();it.hasNext();) 
        {
            String key = (String)it.next();//key值
            System.out.print(key + ":");
            System.out.println(songProperties.getProperty(key));//通过key得到value
            System.out.println();
        }
    }
}

这里写了四个例子,分别为了用于后面讲解四种集合配置元素的使用。

Song1.java

package com.springinaction.springidol;

public class Song1 implements Song {
    public void play() {
        System.out.println("是他就是他,是他就是他,我们的英雄,小哪吒!......");
        System.out.println();
    }
}

Song2.java

package com.springinaction.springidol;

public class Song2 implements Song {
    public void play() {
        System.out.println("让我们荡起双桨,小船儿随风飘荡~......");
        System.out.println();
    }
}

Song3.java

package com.springinaction.springidol;

public class Song3 implements Song {
    public void play() {
        System.out.println("梦里梦到醒不来的梦,梦境里被囚禁的红......");
        System.out.println();
    }
}

XML文件中集合注入元素的具体配置

    <bean id="songJavaer3" class="com.springinaction.springidol.SongJavaer3">
        <!-- 通过<list>元素注入,可以显示重复的bean -->
        <property name="songCollection">
            <list>
                <ref bean="song1"/>
                <ref bean="song2"/>
                <ref bean="song3"/>
                <ref bean="song3"/>
            </list>
        </property>

        <!-- 通过<set>元素注入,不显示重复的bean -->
        <property name="songList">
            <set>
                <ref bean="song1"/>
                <ref bean="song1"/>
                <ref bean="song1"/>
            </set>
        </property>

        <!-- 通过<map>元素注入 -->
        <property name="songMap">
            <map>
                <entry key="《哪吒》" value-ref="song1" />
                <entry key="《让我们荡起双桨》" value-ref="song2" />
                <entry key="《红玫瑰》" value-ref="song3" />
            </map>
        </property>

        <!-- 通过<props>元素注入 -->
        <property name="songProperties">
            <props>
                <prop key="《哪吒》">是他就是他,是他就是他,我们的英雄,小哪吒!......</prop>
                <prop key="《让我们荡起双桨》">让我们荡起双桨,小船儿随风飘荡~......</prop>
                <prop key="《红玫瑰》">梦里梦到醒不来的梦,梦境里被囚禁的红......</prop>
            </props>
        </property>
    </bean>
    <bean id="song1" class="com.springinaction.springidol.Song1" />
    <bean id="song2" class="com.springinaction.springidol.Song2" />
    <bean id="song3" class="com.springinaction.springidol.Song3" />

<map>有四个属性值,如下:

属性 目的
key 指明map的键,取String
key-ref 指明map的键,取bean的引用(id)
value 指明map的值,取String
value-ref 指明map的值,取bean的引用(id)

main方法中进行测试

package com.springinaction.springidol;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/** * 用来测试的main函数 * @author 白鑫 * @date 2016-1-6下午11:36:08 */
public class MainTest {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
        "com/springinaction/springidol/spring-idol.xml");
        Coder coder = (Coder) ctx.getBean("songJavaer3");
        coder.perform();
    }
}

控制台输出为:

Trigl一边写Java博客一边听歌
————————我是可爱的分割线————————
播放songCollection中的歌曲......

是他就是他,是他就是他,我们的英雄,小哪吒!......

让我们荡起双桨,小船儿随风飘荡~......

梦里梦到醒不来的梦,梦境里被囚禁的红......

梦里梦到醒不来的梦,梦境里被囚禁的红......

————————我是可爱的分割线————————
播放songList中的歌曲......

是他就是他,是他就是他,我们的英雄,小哪吒!......

————————我是可爱的分割线————————
播放songMap中的歌曲......

《哪吒》:是他就是他,是他就是他,我们的英雄,小哪吒!......

《让我们荡起双桨》:让我们荡起双桨,小船儿随风飘荡~......

《红玫瑰》:梦里梦到醒不来的梦,梦境里被囚禁的红......

————————我是可爱的分割线————————
播放songProperties中的歌曲......

《让我们荡起双桨》:让我们荡起双桨,小船儿随风飘荡~......

《哪吒》:是他就是他,是他就是他,我们的英雄,小哪吒!......

《红玫瑰》:梦里梦到醒不来的梦,梦境里被囚禁的红......

2.4 注入空

是的少年,你没有听错,的确是注入空或者说是null。第一个原因是为了初始化属性的值,另一个原因是覆盖自动装配的值,配置方式如下:

<property name="someNonNullProperty"><null/></property>

你可能感兴趣的:(spring,bean,集合)