Spring除了构造器注入,还可以通过类的set()方法注入。为了演示这个过程,现在有请下一位参赛者kenny。kenny是一位天赋异禀的乐器演奏者,现定义一个乐器演奏师类:
1 | public class Instrumentalist implements Performer{ |
乐器Instrument接口:
1 | public interface Instrument{ |
setter注入简单值
可以通过InstrumentList类的默认构造器来实例化该Bean,但没有给song和instrument属性赋值的话显然没有什么意义。Spring可以用<property>
元素给属性Song注入值:
1 | <bean id="kenny" class="com.spring.entity.Instrumentalist"> |
name为属性名,value为属性值。
引用其他的Bean
有了歌曲,kenny现在还差乐器。定义一个piano类,实现Instrument接口:
1 | public class Piano implements Instrument{ |
有了piano类,现在我们在Spring容器中定义这个钢琴类:
1 | <bean id="piano" class="com.spring.entity.Piano"/> |
有了钢琴,现在我们把钢琴交给kenny,修改kenny的<bean>
配置:
1 | <bean id="kenny" class="com.spring.entity.Instrumentalist"> |
ref属性指向之前定义的piano<bean>
。
现在我们让kenny正式上台表演:
1 | public class Play { |
输出:
1 | 开灯 |
注入内部Bean
kenny是一个占有欲很强的人,他不希望自己的钢琴被别人使用。这时候我们不能像上面那样引用piano<bean>
了,因为这样任何一个<bean>
都可以引用它。
现在修改kenny的<bean>
:
1 | <bean id="kenny" class="com.spring.entity.Instrumentalist"> |
如你所见,内部Bean是直接声明一个<bean>
元素作为<property>
元素的子节点而定义的。同样,构造器注入也支持内部Bean的声明。 细心的你 会发现内部Bean没有定义id属性,实际上在这里定义id属性是完全合法的,只不过对于内部Bean,id属性显然不重要了。
使用Spring P装配属性
<property>
元素的写法可以更简略,只需在<beans>
加入如下代码:
1 | xmlns:p="http://www.springframework.org/schema/p" |
通过这段代码,我们可以使用p:作为<bean>
元素的所有属性的前缀来装配Bean的属性。现修改kenny的<bean>
配置:
1 | <bean id="kenny" class="com.spring.entity.Instrumentalist" |
装配集合
当配置集合类型的Bean属性时,Spring提供了相应的集合配置元素:
集合元素 | 用途 |
---|---|
<list> | 装配list类型的值,允许重复 |
<set> | 装配set类型的值,不允许重复 |
<map> | 装配map类型的值,名称和值可以是任意类型 |
<props> | 装配properties类型的值,名称和值都必须是String类型 |
为了展示Spring装配集合,现在有请下一位参赛者hank。hank是一位才华横溢的一人乐队,可以同时演奏多种乐器。现定义一个OneManBan类:
1 | public class OneManBan implements Performer{ |
装配List,Set和Array
现在再定义两个乐器类,并在Spring容器中定义它:
1 | <bean id="saxophone" class="com.spring.entity.Saxophone"/> |
现在把所有乐器都装配给hank:
1 | <bean id="hank" class="com.spring.entity.OneManBan"> |
还可以使用其他的Spring设置元素设置<list>
的成员。包括<value>
,<bean>
,</null>
甚至<list>
。
实际上,instruments属性只要是java.util.collection
的实现类型都可以使用<list>
,如:
1 | java.util.List<Instrument> instruments; |
或者:
1 | Instrument[] instruments; |
<set>
元素的使用与<list>
完全一致,唯一区别在于<set>
元素的成员都是唯一的。
现在实例化hank查看输出:
1 | 开灯 |
装配Map集合
如果instruments属性是一个Map集合的话,我们又该如何装配呢?现修改OneManBan类:
1 | public class OneManBan implements Performer{ |
hank<bean>
修改如下:
1 | <bean id="hank" class="com.spring.entity.OneManBan"> |
<map>
的<entry>
由key和value组成:
属性 | 用途 |
---|---|
key | 键为String |
key-ref | 键为Spring容器中其他Bean的引用 |
value | 值为String |
value-ref | 值为Spring容器中其他Bean的引用 |
装配Properties集合
当key和value都是String类型的时候,我们可以使用Properties来代替Map
修改OneManBan:
1 | public class OneManBan implements Performer{ |
修改<bean>
:
1 | <bean id="hank" class="com.spring.entity.OneManBan"> |