Technorati 标记: spring,依赖注入,ioc

接上一篇spring 依赖注入 ,讲解了spring依赖注入的方式(构造器注入,set注入,静态工厂注入和实例工厂注入),这一次我们深入到spring依赖注入配置文件去。

在 sprint 依赖注入方式上,可以知道是使用 和 来注入依赖对象和基本值(基本数据类型和String值)。现在我们将详细谈一下各种值的配置方式。

一、基本值(基本数据类型和String)

在xml配置文件里,使用属性”value“来指定参数的值。顺带提一下的是,javaBeans 里的PropertyEditors 会将这些string值转换为对应的的数据类型。如下:

destroy-method="close">

现在来看一下一种更加简洁的配置,使用 p 命名空间,如下:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

三、其他 bean的索引(依赖对象)

在或元素内部还可以使用ref元素.用来将bean中指定属性的值设置为对容器中的另外一个bean的引用。ref 有三个属性 bean,local,parent。其具体区别如下:

四、内部 bean

在或元素内部还可以使用来定义一个内部bean,如下:

提醒一下的是,在内部 bean 的定义里,不需要指定 id 或者 name 属,也不需要指定 scope ,这些都会自动被容器忽略。内部 bean 的创建都是伴随着 outer bean的创建而创建。

五、Collections

可以使用元素,,和来设置java collection 里的List、Set、Map和Properties的值。如下:

administrator@example.org
support@example.org
development@example.org
a list element followed by a reference
just some string

提醒一下的是,在Map的key或 value里,Set的value,同样可以使用如下元素:

bean | ref | idref | list | set | map | props | value | null

六、Collection 合并

spring容器同样支持Collection的合并。我们可以在父元素里定义,,,,接着可以在子元素里定义,,,来继承或者覆盖父元素的集合。合并结果就是子元素里拥有一个合并了父、子元素里集合的Collection。如下:

administrator@example.com
support@example.com
sales@example.com
support@example.co.uk

注意在子元素里设置了 “merge = true”,那上面合并结果如下:

administrator=administrator@example.com
sales=sales@example.com
support=support@example.co.uk

从父元素继承了,同时覆盖了当中的support的元素。

类似的,,,也具有同样地用法。不过,在使用到元素里,其内元素的顺序依然保持着,父元素的list 总所有子元素的list之前。而 Set、Map和Properties并不存在元素的顺序问题。

七、Collection 合并的限制

在合并Collection里,不能合并类型不一致的Collection(如Set和List)。同时,如果需要抛出异常,则在子元素里的异常必须是父元素的异常的子类。需要注意的是,如果是在父元素里设置了“merge=true”,并不能得到想要的合并效果。

八、泛型集合

在java 5 之后,可以使用泛型集合。spring的类型转换机制同样支持这种泛型集合的使用。如下:

public class Foo {
private Map accounts;
public void setAccounts(Map accounts) {
this.accounts = accounts;
}
}

xml配置文件如下:

当foo需要被注入时,Map的泛型信息会通过反射来获得。spring的类型转换机制可以识别出属性value的值时Float类型的,之后就将String类型的“9.99,2.75,3.99”转换为String类型。

九、null 和 空字符串值

如下例子,会将“email”设置为空字符串(“”)。

上面的例子等同于java 代码:exampleBean.setEmail(“”),类似的,看一下如何设置 null 值,

       如上例子,等同于java 代码:exampleBean.setEmail(null)

十、p 命名空间与简化配置

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd">

p:email="foo@bar.com"/>

如上所示,演示p 命名空间的使用,深入一点来看,如果使用p 命名空间指向依赖对象:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
class="com.example.Person"
p:name="John Doe"
p:spouse-ref="jane"/>

如上,同样演示了传统的用法和使用 p 命名空间的索引指向 bean jane。传统用法是 ,而在 p 命名空间则是p:spouse-ref="jane",-ref 说明spouse不是基本的数据类型或String,而是一个索引。

十一、c 命名空间

p 命名空间是用来简化的配置,类似的有,c 命名空间可用来简化的配置。如下:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

同时也看一下使用 c 命名空间的索引应用,同样是使用 -ref,

十二、复合属性名

有时候可能会看到如下的一些配置,

如上的其实是一个复合属性的名应用,怎么理解呢??在bean foo 理由有一个property fred,同样地在 property fred里有一个property bob,在property bob里有一个property sammy ,最后将“123”赋值给sammy。要让上述操作可以行,要求fred 和 bob 都不能为空。

十三、使用 depends-on

有时候在创建某个bean之前,需要先创建另外一个bean,这时就需要用到属性 depends-on。

使用depends-on,就要求在实例化 beanOne 之前,先实例化 manager。那又该如何先实例化多个bean呢??可以使用逗号,分号或者空格来分开,如下:

如上,这就要求在实例化 beanOne之前,先实例化manager和accountDao。

十四、使用 lazy-init

ApplicationContext实现的默认行为就是在启动时将所有singleton bean提前进行实例化(也就是依赖注入)。通常情况下这是件好事,因为这样在配置中的任何错误就会即刻被发现。有时候这种默认处理方式并不是你想要的,你希望某个bean在需要的时候才实例化,即在第一次向容器通过getBean索取bean时才实例化的。,这种方式称为“懒加载”,使用属性lazy-init可以达到这个效果。

值得提醒一下的是,lazy-init 设置只对scop属性为singleton的bean起作用。另外,在容器层次中通过在元素上使用'default-lazy-init'属性来控制延迟初始化也是可能的。如下面的配置:

     如果一个bean的scope属性为scope=“pototype“时,即使设置了lazy-init="false",容器启动时不实例化bean,而是调用getBean方法是实例化的。