7.5.3 配置依赖
7.5.3 配置依赖
根据前面的介绍,Java
应用中各组件相互调用的实质可以归纳为依赖关系,根据注入方式的不同,Bean
的依赖注入通常有如下两种形式。
- 设值注入:通过
<property>
元素驱动Spring
执行setter
方法。 - 构造注入:通过
<constructor-arg>
元素驱动Spring
执行带参数的构造器。
不管是设值注入,还是构造注入,都视为Bean
的依赖,接受Spring
容器管理,依赖关系的值要么是一个确定的值,要么是Spring
容器中其他Bean
的引用。
通常不建议使用配置文件管理Bean
的基本类型的属性值;通常只使用配置文件管理容器中Bean
与Bean
之间的依赖关系。
对于singleton
作用域的Bean
,如果没有强行取消其预初始化行为,系统会在创建Spring
容器时预初始化所有的singleton Bean
,与此同时,该Bean
所依赖的Bean
也被一起实例化。BeanFactory
与ApplicationContext
实例化容器中Bean
的时机不同:前者等到程序需要Bean
实例时才创建Bean
:而后者在容器创建Application Context
实例时,会预初始化容器中所有的singleton Bean
。
因为采用ApplicationContext
作为Spring
容器,创建容器时会同时创建容器中所有singleton
作用域的Bean
,因此可能需要更多的系统开销。但一旦创建成功,应用后面的响应速度更快,因此,对于普通的Java EE
应用,推荐使用ApplicationContext
作为Spring
容器.
创建BeanFactory
时不会立即创建Bean
实例,所以有可能程序可以正确地创建BeanFactory
实例,但当请求Bean
实例时依然抛出一个异常:创建Bean
实例或注入它的依赖关系时出现错误。
配置错误的延迟出现,也会给系统引入不安全因素,而ApplicationContext
则默认预实例化所有singleton
作用域的Bean
,所以ApplicationContext
实例化过程比BeanFactory
实例化过程的时间和内存开销大,但可以在容器初始化阶段就检验出配置错误。
除此之外, Spring
可以为任何Java
对象注入任何类型的属性—只要该Java
对象为该属性提供了应的setter
方法即可。
例如,如下配置片段:
1 | <bean id="id" class="lee.AClass"> |
对于上面的配置片段,有效的数据只是那些粗体字内容, Spring
将会为每个<bean>
元素创建一个Java
对象—这个Java
对象就是一个Bean
实例。对于上面的程序, Spring
将采用类似于如下的代码创建Java
实例。
1 | // 获取lee.AClass类的Class对象 |
创建该实例后, Spring
接着遍历该<bean>
元素里所有的<property>
子元素,<bean>
元素每包含一个<property>
子元素, Spring
就为该bean
实例调用一次setter
方法。对于上面第一行<property>
子元素,将有类似的如下代码:
1 | // 获取第一个<property>元素的name属性值对应的 setter方法名 |
通过类似上面的代码, Spring
就可根据配置文件的信息来创建Java
实例,并调用该Java
实例的setter
方法(这就是所谓的设值注入)
对于如下配置片段:
1 | <bean id="id" class="lee.AClass"> |
上面的配置片段指定了两个<constructor-arg/>
子元素, Spring
就不再采用默认的构造器来创建Bean
实例,而是使用特定构造器来创建该Bean
实例。Spring
将会采用类似如下的代码来创建Bean
实例:
1 | // 获取lee.AClass类的Class对象 |
上面的程序片段仅是一个示例, Spring
实际上还需要根据<property>
元素、<contructor-arg>
元素所使用的value
属性、ref
属性等来判断需要注入的到底是什么数据类型,并要对这些值进行合适的类型转换,所以Spring
实际的处理过程更复杂。
由此可见,
构造注入就是通过<constructor-arg>
驱动Spring
执行有参数的构造器;
设值注入就是通过<property>
.驱动Spring
执行setter
方法。
不管哪种注入,都需要为参数传入参数值,而Java
类的成员变量可以是各种数据类型,除了基本类型值、字符串类型值等,还可以是其他Java
实例,也可以是容器中的其他Bean
实例,甚至是Java
集合、数组等,所以Spring
允许通过如下元素为setter
方法、构造器的参数指定参数值。
value
ref
bean
list
,set
,map
,props
上面4种情况分别代表Bean
类的4种类型的成员变量,下面详细介绍这4种情况。