Spring内核研究-管理bean之间的关系三(自动装配)
Spring BeanFactory提供了类似pico container中自动装配组件依赖的对象的功能。自动装配能应用在每个组件上,可以为一些组件定义自动装配,而另一些组件则不使用。
使用”autowire”属性可以设置自动装配,autowire有五种模式:
no
默认属性,不进行自动装配。
byName
通过bean的属性名称自动装配合作者。
SHAPE \* MERGEFORMAT
|
|
按照bean定义的名称自动装配 |
Spring用bean 中set方法名和BeanFactory中定义的合作者的名称做匹配,一但2者匹配,Sping就会把合作者进行注入。
可以使用id属性也可以使用name属性定义合作者的名称,这2个属性在Spring进行自动装配时没有区别。
当有多个名称相同的合作者在Spring中定义时,Srping在自动装配时选择最后一个定义的合作者注入。
SHAPE \* MERGEFORMAT
|
这个Bean将被注入到dao中 |
在多个合作者名称相同进行自动装配时,合作者的id属性并不会比name属性优先处理。无论怎样定义Spring总会把最后一个定义的合作者注入。
byType
通过bean set方法中参数的类型和BeanFactory中定义合作者的类型做匹配,Spring会找到匹配的合作者进行注入。
SHAPE \* MERGEFORMAT
|
|
按照bean定义的类型自动装配 |
在byType自动装配模式中,Spring不关心合作者的名称,只关心合作者的类型是否满足条件。
类似上面介绍的byName的方式,在byType方式中,
当具有相同名称并且有相同类型的多个合作者被找到时,Spring会注入最后一个定义的合作者。
SHAPE \* MERGEFORMAT
|
这个Bean将被注入到dao中 |
在byType装配时,如果有2个不同名称但是类型相同的合作者被找到,那么Spring会抛出一个依赖异常。
SHAPE \* MERGEFORMAT
|
抛出依赖异常,通知用户在byType方式中同样类型的Bean只能定义一个。
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dao' defined in class path resource [research/spring/beanfactory/ch3/context.xml]: Unsatisfied dependency expressed through bean property 'database': There are 2 beans of type [class research.spring.beanfactory.ch3.Database] for autowire by type. There should have been 1 to be able to autowire property 'database' of bean 'dao'...
constructor
constructor其实时按byType的方式进行构造函数的注入。
constructor其实时按byType的方式进行构造函数的注入。
SHAPE \* MERGEFORMAT
|
|
按照bean定义的类型自动装配 |
constructor装配方式不关心构造参数的顺序,无论构造函数参数的顺序如何Spring都会按类型匹配到正确的合作者进行注入。
在byType方式中,当没有找到类型相同的合作者时Spring什么都不会去做。但是在constructor方式中,当没有找到和Bean构造函数中参数类型相匹配的合作者时,Spring会抛出异常。
Spring在进行constructor方式的自动装配时,强制要求所有的构造函数中所有的合作者都必须存在。
autodetect
在autodetect的方式中,Spring检查一个Bean内部是否有默认的构造函数。如果有默认的参数Spring就使用byType的方式进行自动装配。如果没有默认的构造函数Spring则使用constructor的方式进行自动装配。
如果一个Bean同时定义了默认构造函数和带参数的构造函数,Spring仍会使用byType的方式进行装配。
不管使用上述哪种装配方式,都可以在Bean中显示的定义合作者。显示定义的依赖关系优先级比自动装配高。
自动装配的功能可以和自动依赖检查一起使用。Spring会首先进行自动装配,然后在进行依赖检查。
自动装配提供了简化配置的可能性,但是我并不建议在项目中大量的使用自动装配,特别时byType方式。因为自动装配,尤其时byType方式,破坏了Bean和合作者之间显示的依赖关系,所有的依赖关系都时不明显的。在使用自动装配后我们的依赖关系需要到源代码中才能看到,这使得维护或文档化Bean的依赖关系变得很困难。
适当的使用自动装配比如byName方式的装配,是有一些好处的。比如我们在一些特定的范围里可以借助byName自动装配的功能来实现“
以惯例来代替配置”的框架。