springBean装配

通过Set方法注入依赖,设值注入不是冬天预防流感的东西。它是一种基于标准命名规范的设置Bean属性的技术。JavaBean规范规定使用对应的 set和get方法来设置和获得Bean的属性值,这种方法早已普遍使用。例如,一个maxStudents属性有以下get和set方法:
public void setMaxStudents(int maxStudents){
this.maxStudents= maxStudents;
}
public int getMaxStudents(){
return maxStudents;
}
Bean属性有这些方法,为什么不让Spring使用它们来配置Bean呢?实际上,在应用系统中我们有很多Bean有这种属性。通过使 用<property>的子元素<value>可以按照下面的方式设置基本类型属性,如int和float,或 java.lang.String:

例如,courseService Bean可以使用它的maxStudents属性设置一个课程的最大座位数。为了限制每门课程的注册学生数最多为30名,这样修改courseService的定义:
<bean id=”courseService” class=”com.springinaction.CourseService”>
<property name=”maxStudents”>
<value>30</value>
   </property>
</bean>
这里设置了一个int属性,你可以用同样的方式来设置任何基本类型和String型属性。Spring将自动判断设置的属性类型并且将其转换成合适的值。
现在,你知道如何给Bean设置简单类型的属性了。但是,复杂类型的属性,该怎么办呢?
引用其他Bean,信不信由你,Bean建立社交关系不是说让他们去约会单身Bean朋友或到Bean单身酒吧去。而是,通过与Bean定义相同的方式---容器的XML文件知道应用系统中的其他Bean。
就像我们在前面所作的,我们使用<property>元素来设置指向其他Bean的属性。<property>的子元素<ref>让我们实现这一点:

例如,回想一下,CourseServiceImpl类在验证一个学生是否符合本课程的要求时需要用到StudentService的引用。这个 引用通过CourseServiceImpl的setStudentService()方法装配进来,修改XML文件中的Bean courseService定义:

容器赋给courseService Bean一个studentService的实例(通过setStudentService()方法),这样CourseServiceImpl就不用自己负责寻找StudentService了。
内部Bean,另一种不常使用的装配Bean引用的方法是在<property>元素中嵌入一个<bean>元素。例如,courseService Bean的studentService属性也可以这样装配:

这种装配Bean引用的方式的缺点是你无法在其他地方重用这个StudentServiceImpl实例,因为它是一个专门为 courseService Bean建立的实例。你也许会发现内部Bean定义会影响XML文件的可读性。另一方面,如果我们想让一个具体Bean实例只对它的包装类可见,对其他 Bean不可见,这种方式倒是非常有用。
装配集合,如果你有一个属性是一个列表或是一个Bean引用集合怎么办呢?没问题,Spring支持多种类型的集合作为属性。
XML 类型
<list> java.util.List, arrays
<set> java.util.Set
<map> java.util.Map
<props> Java.util.Properties
装配集合并不比装配单个属性难。不是使用<value>或<ref>元素。而是使用上面表中的一种。
装配List和数组,无论你有一个属性是数组,还是有一个属性是某种类型的java.util.List,你都需要使用<list>元素来装配这个属性,如下:

装配Set,List非常重要,但如果你的Bean需要一个java.util.Set属性以确保集合中数据的唯一性,该怎么配置呢?这就需要使用<set>元素:

注意,<set>的使用方法和<list>是一样的。唯一不同的地方是它被装配到什么样的属性中。<list>是向java.util.List或数组里装配数据,而<set>是向java.util.Set中装配数据。
装配Map,在Spring中,你可以使用<map>元素来装配java.util.Map集合。Map集合中的每条条目是由一个主键和一个数值组成的,用<entry>元素来定义一条条目:

Map中的<entry>的数值和<list>以及<set>的一样,可以是任何有效的属性元素。重申一 遍,包括<value>、<ref>、<list>甚至是另一个<map>。注意,配 置<entry>时,属性key的值只能是String,这对于java.util.Map的功能 有一点限制,java.util.Map是允许任何类型的对象作为主键的。然而,这点局限一般没问题,因为Map通常是用String作为主键的。
装配Properties,java.util.Properties集合是最后一个能在Spring中装配的集合类。使用<props>元素来装配它。使用<prop>元素表示每条属性。
在很多地方,<props>和<map>的使用方法都很相似。他们最大的区别是<prop>的值只能是String型,所以没有必要使用<value>元素来区分String型数值和非String型数值:

设置null,到目前为止,我们已经讲解了如何配置Bean的属性,包括基本类型、集合或系统中的其他Bean。但是如果为了满足需求,你需要明 确地将一个属性的值设置为null该怎么办呢?这确实是另一种装配方式,只有在这样的情况下我们才装配一个null而不是一个数值或其他Bean。
为了将一个属性设为null,你只要使用<null/>元素就行了。例如为了设置属性foo的值为null,你可以这样写:
<property name=”foo”><null/></property>
通过构造函数注入依赖,使用Set注入时,我们通过<property>元素来注入属性的值。构造函数注入也一样,只不过是通 过<bean>元素下的<constructor-arg>元素来指定实例化这个bean的时候需要传递的参数。这两种方式的一 个不同的地方是,<constructor-arg>没有name属性,而<property>有name这个属性。下面这个例 子显示了构造函数注入法的配置:
<bean id=”foo1” class=”com.springinaction.Foo1”>
<constructor-arg>
<value>42</value>
</constructor-arg>
</bean>

<bean id=”foo2” class=”com.springinaction.Foo2”>
<constructor-arg>
<ref bean=”bar”/>
</constructor-arg>
</bean>
解决构造函数参数的不确定性,例如你的Bean的构造函数有一个String参数和一个java.net.URL参数
public class Foo{
public Foo(String arg1,java.net.URL arg2){
}
}
java.net.URL类型和String类型都可以从<value>元素转变而来。所以哪个传递给arg1,哪个传递给arg2呢?

两个<constructor-arg>元素的值看上去都像URL。也许你认为Spring会按造顺序分配,其实这是不确定的。
有两种解决办法:


自动装配,到目前为止,你已经了解了如何显示地使用<property>元素来装配Bean的所有属性。或者,你可以让Spring自动装配,只要设置需要自动装配的<bean>中的autowire属性。

有四种自动装配的类型:
 byName—试图在容器中寻找和需要自动装配的属性名相同的Bean(或ID).如果没有找到,这个属性就没有被装配上。
 byType ---试图在容器中寻找一个与需要自动装配的属性类型相同的Bean。如果没有找到相符的Bean,这个属性就没有被装配。如果找到超过一个相符的Bean,会抛出异常。
 constructor---试图在容器中查找与需要自动装配的Bean的构造函数参数一致的一个或多个Bean。
 autodetect---首先尝试使用constructor来自动装配,然后使用byType方式。不确定性的处理与constructor和byType方式一样。
1. 处理自动装配中的不确定性
Spring无法解决不确定性。
2. 混合使用自动和手动装配

3. 缺省自动装配
<beans default-autowire=”byName”>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值