2.3 setter注入bean的属性
典型的,bean提供一对函数用来访问属性的:setXXX()和getXXX()。Spring利用这点进行setter注入。
为了实力Spring其它方式的DI,下面是另外一个performer。Kenny是个不错的演奏家,定义如下:
package com.springinaction.springidol;
publicinterface Instrument {
    void play();
}
package com.springinaction.springidol;
publicclass Instrumentalist implements Performer {
    private String song;
    private Instrument instrument;
   
    public Instrumentalist(){}
   
    publicvoid perform() throws PerformanceException {
       System.out.println("Playing " + song + " : ");
       instrument.play();
    }
    public String getSong() {
       returnsong;
    }
    publicvoid setSong(String song) {
       this.song = song;
    }
    public Instrument getInstrument() {
       returninstrument;
    }
    publicvoid setInstrument(Instrument instrument) {
       this.instrument = instrument;
    }
}
Kenny可以在bean元素中进行如下定义:
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist">
</bean>
尽管这样kenny就定义好了,但是没有song和instrument,kenny是无法演奏的。下面介绍如何通过setter方法来注入。
2.3.1注入简单的数值
Bean的属性可以通过spring中的property元素来进行配置,property同constructor-arg有很多类似的地方。除了一个是通过构造器,一个通过setter方法。
下面看看怎么进行注入
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist">
    <property name="song" value="Jingle Bells"/>
</bean>
一旦Instrumentalist被初始化,Spring用setter方法把<property>里面设置的值注入到对象中。这个例子把Jingle Bells放入到kenny的song属性中。同一下的代码类似:
Instrumentalist Kenny = new Instrumentalist();
kenny.setSong(“Jingle Bells”);
但这个同spring配置生成有最重要的不同,就是spring提供了代码的松耦合,spring的方法更灵活。
在song的属性这个例子中,<property>注入了一个String的类型的值,不过<property>还可以注入别的类型,int,float,boolean,java.lang.Double等等.
看下面配置:
    <bean id="kenny" class="com.springinaction.springidol.Instrumentalist">
       <property name="song" value="Jingle Bells"/>
       <property name="age" value="37"/>
    </bean>
注意value属性的使用,字段是String和int没有什么区别,Spring根据字段属性来自动决定正确的类型。因此,age是int,Spring自动把37转换成int类型的。
使用<property>来对普通的属性值来赋值非常不错,但DI应该是比这样写在xml文件里更好的东西。DI插入的真实数据是在程序中合作的对象中的,因此它们不需要捆绑在一起。Kenny的程序示例一下如何做。
2.3.2使用其他的bean
Kenny可以使用任何给他的乐器,只要这个乐器继承与Instrument接口。当然,kenny有最喜欢的乐器,saxophone,下面代码定义一个saxophone:
package com.springinaction.springidol;
publicclass Saxophone implements Instrument {
    public Saxophone() {}
    publicvoid play() {
       System.out.println("TOOT TOOT TOOT");
    }
}
在给kenny演奏前,必须要把它定义一下
<bean id="saxophone" class="com.springinaction.springidol.Saxophone"/>
那么kenny的bean定义也要修改一下
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist">
    <property name="song" value="Jingle Bells"/>
    <property name="instrument" ref="saxophone"/>
</bean>
现在kenny已经被注入了所有的属性,并且可以开始演出。跟duke一样,我们可以这样来执行:
String path=”com/springinaction/springidol/spring-idol.xml”;
ApplicationContext context = new ClassPathXmlApplicationContext(path);
Performer performer = (Performer)context.getBean(“kenny”);
performer.perform();
这并不是idol比赛,但可以是kenny实验一下,打印输出:
Playing Jingle Bells : TOOT TOOT TOOT
同时,这个例子还展示了一个重要的地方,如果你跟duke执行的代码比较,你发现没什么不一样,但是,唯一的不同点在于,从Spring获得的名字不同。代码是相同的,但产生了一个魔术师,一个演奏者。
这不是spring的优点,而是对接口编程的号称。通过一个Performer接口的对象,我们可以使用任何performer,不论是什么诗人还是弹琴的。Spring因此鼓励使用interface。不过你会看到,面向接口编程和Spring的DI是代码更松散。
上面提过,kenny可以演奏各种乐器,现在给他一个钢琴。代码如下:
package com.springinaction.springidol;
publicclass Piano implements Instrument {
    public Piano() {}
    publicvoid play() {
       System.out.println("PLINK PLINK PLINK");
    }
}
Bean的声明如下
<bean id="piano" class="com.springinaction.springidol.Piano"/>
想让kenny演奏钢琴,kenny的bean也需要改一下。
    <bean id="kenny" class="com.springinaction.springidol.Instrumentalist">
       <property name="song" value="Jingle Bells"/>
       <property name="instrument" ref="piano"/>
    </bean>
这样,kenny就可以弹钢琴了,代码不需要任何改变。因为Instrumentalist只通过Instrument接口知道它本身的instrument的属性。这样,kenny可以弹saxophone或者piano,两者分散。如果kenny想演奏hammered dulcimer,只需要加入一个类,并且修改xml文件即可。
内部类注入
86-87 I don’t care about that. Maybe I will look it later. But not now.

2.3.3捆绑集合

到了现在,介绍了spring配置基本类型(通过value)和其他类(通过ref)但value和ref只有在你的属性是单一的时候才有效。那么当属性是复数(就是集合)时spring怎么做呢?

Spring提供了4个类型的集合配置元素。参看2.3表

<list>和<set>当属性是array或者是一些java.util.Collection时候非常有用。下面会看到,实际实现的用来定义属性的collection,跟使用<list>还是<set>没有任何关系。两个元素都可以不经修改的使用在任何collection上。

对于<map><props>,对应是java.util.Map和java.util.Properties。这些都是值键对于的一对一对的。唯一两个不同就是props要求值键都是String。Map则没有要求。

下面是在spring中捆绑collection,Hank现在来到了SpringIdel舞台。他是一个人的乐队,跟kenny一样,他能够演奏多种乐器,不过hank是同时演奏。Hank的代码如下:

package com.springinaction.springidol;

import java.util.Collection;

public class OneManBand implements Performer {

private Collection<Instrument> instruments;

public OneManBand() {}

public void perform() throws PerformanceException {

for(Instrument instrument : instruments){

instrument.play();

}

}

public void setInstruments(Collection<Instrument> instruments) {

this.instruments = instruments;

}

}

程序中,当OnManBand执行perform方法的时候对collection进行遍历。这里最重要的是instrutment的注入是通过setter方法。看看Spring怎么支持这个collection。

ListsArrays

Hank要使用乐器,用list来提供给他

<bean id="hank" class="com.springinaction.springidol.OneManBand">

<property name="instruments">

<list>

<ref bean="guitar"/>

<ref bean="cymbal"/>

<ref bean="harmonica"/>

</list>

</property>

</bean>

<list>元素包含1个或多个值。<ref>用来指向在SpringContext里的其它bean的实例,配置了hank可以弹奏guitar,cymbal,harmonica。这里可以使用其它Spring的赋值的元素,比如<bean>,<value>甚至<null/>。另外,list可以包含另外一个list,多维概念。

在OneManBand类的代码中,instruments使用的是jdk1.5的java.util.Collection。但<List>用来工作在那些的属性,它们是实现Collection或者是一个数组。就是说,<list>在以下的代码上照常工作

java.util.List<Instrument> instruments;

Instrument[] insruments;

Sets

<list>元素更关心的是Spring如何处理这些collection,而不是它的类型。你可以在用到List的地方改用set。<set>有<list>没有的好处:保证每个元素唯一。不一样的元素会被忽略。

跟<list>一样,<set>的元素类型也是collection和array。

Maps

当OneManBand执行时,每种乐器的声音在perform方法中被打印出来。但我们想看到每个音符是哪个乐器弹奏的,代码需要修改一下:

package com.springinaction.springidol;

import java.util.Map;

public class OneManBand implements Performer {

private Map<String,Instrument> instruments;

public OneManBand() {}

public void perform() throws PerformanceException {

for(String key : instruments.keySet()){

System.out.println(key + " : ");

Instrument instrument = instruments.get(key);

instrument.play();

}

}

public void setInstruments(Map<String,Instrument> instruments) {

this.instruments = instruments;

}

}

这个代码中,instruments是由键值对组成的,在xml文件中使用下面的定义:

<bean id="hank" class="com.springinaction.springidol.OneManBand">

<property name="instruments">

<map>

<entry key="GUITAR" value-ref="guitar"/>

<entry key="CYMBAL" value-ref="cymbal"/>

<entry key="HARMONICA" value-ref="harmonica"/>

</map>

</property>

</bean>

<map>元素定义了一个map类型,每一个entry元素定义了map的一个成员。上个例子,key定义了键,value-ref定义了引用的bean的id。

下图是entry里面的元素的含义。

<map>是唯一一个能把不止是String的类型插入的键值对的方法。下面介绍Props。

Props

如果键值都是String,那么就要用到java.util.Properties类了。现在把OneManBand修改一下:

package com.springinaction.springidol;

import java.util.Iterator;

import java.util.Properties;

public class OneManBand implements Performer {

private Properties instruments;

public OneManBand() {}

public void perform() throws PerformanceException {

for (Iterator iter = instruments.keySet().iterator(); iter.hasNext();) {

String key = (String)iter.next();

System.out.println(key + " : " + instruments.getProperty(key));

}

}

public void setInstruments(Properties instruments) {

this.instruments = instruments;

}

}

Xml中做如下修改

<bean id="hank" class="com.springinaction.springidol.OneManBand">

<property name="instruments">

<props>

<prop key="GUITAR">STUM STUM STUM</prop>

<prop key="CYMBAL">CRASH CRASH CRASH</prop>

<prop key="HARMONICA">HUM HUM HUM</prop>

</props>

</property>

</bean>

This is easy to understand the code, it’s not necessary to talk about it.

有些可能有些混淆,看一下

l         <property>是向bean注入一个值

l         <props>是Properties定义的一个元素

l         <prop>是<props>的一个元素

2.3.4捆绑空值

几乎所有情况,都要把值或者java的引用放入一个bean的属性中,但如果要你放入null呢?

对于properties,可以这样

<property name=”someProperty”><null/></properties>

有时需要用null来覆盖自动捆绑,什么是自动捆绑?下面将会讲述。

第二章 bean捆绑基础(3节)相关推荐

  1. 计算机的指令合成为,第二章计算机操作基础知识doc

    第二章计算机操作基础知识doc (29页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 23.9 积分 第二章  计算机操作基础知识第一节  计算机基础知识 ...

  2. 第二章网页前端基础与HTTP协议

    第二章 网页前端基础与HTTP协议 爬虫需要遵循网络传输协议才能与服务器进行通信,当与服务器建立通信后,爬虫才能获取网页内容,从而获取想要爬取的内容.获取到的网页内容通常为HTML(HyperText ...

  3. 第一篇第二章火灾的基础知识

    沿外墙面蔓延的情况 需要注意:层高要足够高 要不下层着火会直接蔓延到上层 喷头系统必须在轰然之前进行灭火 否则灭火失败 2019/1/3 [录播]2018一消精华班-实务-一级消防工程师-环球网校 h ...

  4. 第二章:图像处理基础

    第二章:图像处理基础操作 一.图像的基本表示方法: 1. 二值图像: 2. 灰度图像: 3. 彩色图像: 二.像素处理: 1. 二值图像及灰度图像: 2.彩色图像: 3. 使用numpy.array访 ...

  5. 第二章 Mablab语言基础

    第二章 Mablab语言基础 2.1 Matlab的变量与常量 1) input:x=input('please enter a numb') 2) Inf/inf:正无穷大 3) pi:圆周率 4) ...

  6. java语言定义一个具备栈功能的类_Java学习笔记 第二章 Java语言基础

    第二章 JAVA语言基础 一.关键字 1.关键字的定义和特点 定义:被Java语言赋予了特殊含义的单词 特点:关键字中所有的字母都为小写 2.用于定义数据类型的关键字 c;ass  interface ...

  7. 进击 !!第二章 JAVA编程基础

    第二章 JAVA编程基础 目标: 掌握java的基本语法,常量,变量,流程控制语句,方法以及数组 运用java运算符的使用 了解java代码的基本格式 2.1java 的基本语法 1. 代码的基本格式 ...

  8. 第二章 CortexM3/M4基础

    第二章 CortexM3/M4基础 前言 2.1 Cortex-M3/M4通用寄存器 2.1.1 通用寄存器 1. 通用目的寄存器 R0-R12 1. 功能寄存器 R13-R15 2.1.2 特殊功能 ...

  9. Python基础——第二章:Python基础语法

    前言 本文是根据黑马程序员Python教程所作之笔记,目的是为了方便我本人以及广大同学们查漏补缺. 不想做笔记直接来我的频道.当然啦,自己的笔记才是最好的哦! PS:感谢黑马程序员! 教程链接:黑马程 ...

最新文章

  1. C# 温故而知新:Stream篇(二)
  2. iOS 代理反向传值
  3. 云计算学习(3-3)云计算的由来-应运而生
  4. python调用通达信公式_对照通达信一些指标的Python实现
  5. 深入理解javascript原型和闭包(11)——执行上下文栈
  6. 研究所月入两万,是一种什么体验?
  7. mysql workbench 存储过程_MySQL Workbench创建存储过程教程示例
  8. C++笔记(2018/2/7)
  9. 在计算机中 用于完成系统配置的文件是,历年真题:全国2015年4月自考02323操作系统概论考试试卷以及答案...
  10. python3.5安装包_Python 3.5.4详细图文安装教程(附安装包) | 我爱分享网
  11. SIMATIC HMI操作系统更新
  12. 电脑无损分区大小调整
  13. MySQL数据库创建与维护数据表
  14. 哆啦A梦的神奇口袋 - 这全是宝藏 https://baozangku.com/
  15. dnf打团正在连接服务器进不去是吗鬼,DNF韩服大转移版本开启 上线送迷你女鬼剑宠物...
  16. C51单片机实现 贪吃蛇
  17. 阿里云ECS服务器组内网
  18. gmx_MMPBSA.py的安装及使用--只翻译部分内容,具体可参考官方文档(https://valdes-tresanco-ms.github.io/gmx_MMPBSA/dev/)
  19. 计算机操作知识 p?p?t,计算机初级基本操作
  20. uml各类图--完整全面实例

热门文章

  1. Spring IOC系列学习笔记五:context:component-scan 节点解析
  2. 二维码教程之如何制作表白二维码
  3. 网站都变成灰色了,它是怎么实现的
  4. Ubutnu18.04解决:Starting Wait until snapd is fully seeded...
  5. 实验五:常见WEB漏洞挖掘与利用
  6. 杨天宇20190905-1 每周例行报告
  7. Codeforces round #628 C.Ehab and Path-etic MEXs
  8. 医学统计学 第八章( t 检验)
  9. 衡阳师范学院计算机考试题库,衡阳师范学院自主招生综合素质测试面试题方法指导...
  10. map与sync.Map