Spring Setter方法注入


Spring除了构造器注入,还可以通过类的set()方法注入。为了演示这个过程,现在有请下一位参赛者kenny。kenny是一位天赋异禀的乐器演奏者,现定义一个乐器演奏师类:

public class Instrumentalist implements Performer{
    private String song;
    private Instrument instrument;
    
    public Instrumentalist() {
    	
    }
    public void perform() {
        System.out.println("唱:"+song+"");
        instrument.play();
    }
    public String screamSong(){
        return song;
    }
    public String getSong() {
        return song;
    }
    //注入歌曲
    public void setSong(String song) {
        this.song = song;
    }
    public Instrument getInstrument() {
        return instrument;
    }
    //注入乐器
    public void setInstrument(Instrument instrument) {
        this.instrument = instrument;
    }
}

乐器Instrument接口:

public interface Instrument{
    public void play();
}

setter注入简单值

可以通过InstrumentList类的默认构造器来实例化该Bean,但没有给song和instrument属性赋值的话显然没有什么意义。Spring可以用元素给属性Song注入值:

<bean id="kenny" class="com.study._002.entity.Instrumentalist">
    <property name="song" value="May Rain"/>
</bean>

name为属性名,value为属性值。

引用其他的Bean

有了歌曲,kenny现在还差乐器。定义一个piano类,实现Instrument接口:

public class Piano implements Instrument{
    public void play() {
        System.out.println("钢琴声响起");
    }
}

有了piano类,现在我们在Spring容器中定义这个钢琴类:

<bean id="piano" class="com.study._002.entity.Piano"/>

有了钢琴,现在我们把钢琴交给kenny,修改kenny的配置:

<bean id="kenny" class="com.spring.entity.Instrumentalist">
    <property name="song" value="May Rain"/>
    <property name="instrument" ref="piano"/>
</bean>

ref属性指向之前定义的piano。

现在我们让kenny正式上台表演:

public class Play {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Instrumentalist kenny=(Instrumentalist)ac.getBean("kenny");
        kenny.perform();
    }
}

输出:

唱:May Rain
钢琴声响起

注入内部Bean

kenny是一个占有欲很强的人,他不希望自己的钢琴被别人使用。这时候我们不能像上面那样引用piano了,因为这样任何一个都可以引用它。

现在修改kenny的:

<bean id="kenny" class="com.study._002.entity.Instrumentalist">
    <property name="song" value="May Rain"/>
    <property name="instrument" >
        <bean class="com.study._002.entity.Piano"/>
    </property>
</bean>

如你所见,内部Bean是直接声明一个元素作为元素的子节点而定义的。同样,构造器注入也支持内部Bean的声明。 细心的你 会发现内部Bean没有定义id属性,实际上在这里定义id属性是完全合法的,只不过对于内部Bean,id属性显然不重要了。

使用Spring P装配属性

元素的写法可以更简略,只需在加入如下代码:

xmlns:p="http://www.springframework.org/schema/p"

通过这段代码,我们可以使用p:作为元素的所有属性的前缀来装配Bean的属性。现修改kenny的配置:

<bean id="kenny" class="com.study._002.entity.Instrumentalist"
    p:song="May Rain"
    p:instrument-ref="piano"/>

装配集合

当配置集合类型的Bean属性时,Spring提供了相应的集合配置元素:

集合元素用途
list装配list类型的值,允许重复
set装配set类型的值,不允许重复
map装配map类型的值,名称和值可以是任意类型
props装配properties类型的值,名称和值都必须是String类型

为了展示Spring装配集合,现在有请下一位参赛者hank。hank是一位才华横溢的一人乐队,可以同时演奏多种乐器。现定义一个OneManBan类:

public class OneManBan implements Performer{
    private Collection<Instrument> instruments;
    
    //注入instruments集合
    public void setInstruments(Collection<Instrument> instruments) {
        this.instruments = instruments;
    }
    
    public void perform() {
        for(Instrument ins:instruments){
            ins.play();
        }
    }
}

装配List,Set和Array

现在再定义两个乐器类,并在Spring容器中定义它:

<bean id="saxophone" class="com.study._002.entity.Saxophone"/>
<bean id="guitar" class="com.study._002.entity.Guitar"/>

现在把所有乐器都装配给hank:

<bean id="hank" class="com.study._002.entity.OneManBan">
    <property name="instruments">
        <list>
            <ref bean="saxophone"/>
            <ref bean="piano"/>
            <ref bean="guitar"/>
        </list>
    </property>
</bean>

还可以使用其他的Spring设置元素设置的成员。包括,,甚至。

实际上,instruments属性只要是java.util.collection的实现类型都可以使用,如:

java.util.List<Instrument> instruments;

或者:

Instrument[] instruments;

元素的使用与完全一致,唯一区别在于元素的成员都是唯一的。

现在实例化hank查看输出:

吹萨克斯
钢琴声响起
弹奏吉他

装配Map集合

如果instruments属性是一个Map集合的话,我们又该如何装配呢?copy修改OneManBan类为OneManBan2:

public class OneManBan2 implements Performer{
    private Map<String,Instrument> instruments;
    public OneManBan2() {
    	
    }
    
    public void perform() {
        for(String key:instruments.keySet()){
            System.out.print(key+": ");
            Instrument ins=instruments.get(key);
            ins.play();
        }
    }
    public void setInstruments(Map<String, Instrument> instruments) {
        this.instruments = instruments;
    }
}

hank修改如下:

<bean id="hank" class="com.study._002.entity.OneManBan">
    <property name="instruments">
        <map>
            <entry key="saxophone" value-ref="saxophone"/>
            <entry key="piano" value-ref="piano"/>
            <entry key="guitar" value-ref="guitar"/>
        </map>
    </property>
</bean>

的由key和value组成:

属性用途
key键为String
key-ref键为Spring容器中其他Bean的引用
value值为String
value-ref值为Spring容器中其他Bean的引用

装配Properties集合

当key和value都是String类型的时候,我们可以使用Properties来代替Map

修改OneManBan类为OneManBan3:

public class OneManBan3 implements Performer{
    private Properties instruments;
    public OneManBan3() {
    	
    }
    public void perform() {
        for(Object key:instruments.keySet()){
            System.out.print(key+": ");
            String ins=instruments.getProperty(key.toString());
            System.out.println(ins);
        }
    }
    public void setInstruments(Properties instruments) {
        this.instruments = instruments;
    }
}

修改:

<bean id="hank" class="com.study._002.entity.OneManBan">
    <property name="instruments">
        <props>
            <prop key="saxophone" >play the saxophone</prop>
            <prop key="piano">play the piano</prop>
            <prop key="guitar">play the guitar</prop>
        </props>
    </property>
</bean>

源码:https://github.com/ReYe0/SpringStudy/tree/master/_002.spring-setter-injection
转载:https://mrbird.cc/Spring-Setter%E6%96%B9%E6%B3%95%E6%B3%A8%E5%85%A5.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值