http://tjc.javaeye.com/blog/341430
今天来整理一下Spring的自动装配autowire一节,在这里我们要解决以下问题:
§1 什么是自动装配?
§2 自动装配的意义?
§3 自动装配有几种类型?
§4 如何启用自动装配?
§5 自动装配将引发的问题?
§1 什么是自动装配?
Springreference 写道
The
Springcontainer is able to
autowirerelationships between collaborating beans. This means that it is
possible to automatically let
Springresolve collaborators (other beans) for your bean by inspecting the contents
of the BeanFactory.
引用
SpringIoC容器可以自动装配(
autowire)相互协作bean之间的关联关系。因此,如果可能的话,可以自动让
Spring通过检查BeanFactory中的内容,来替我们指定bean的协作者(其他被依赖的bean)。
简而言之,就是对于bean当中引用的其他bean不需要我们自己去配置它改使用哪个类,
Spring的自动装配可以帮助我们完成这些工作。
§2 自动装配的意义?
Springreference 写道
It is important to understand the various advantages and disadvantages of autowiring. Some advantages of
autowiring include:
• Autowiring can significantly reduce the volume of configuration required. However, mechanisms such as the
use of a bean template (discussed elsewhere in this chapter) are also valuable in this regard.
• Autowiring can cause configuration to keep itself up to date as your objects evolve. For example, if you need
to add an additional dependency to a class, that dependency can be satisfied automatically without the need
to modify configuration. Thus there may be a strong case for autowiring during development, without ruling
out the option of switching to explicit wiring when the code base becomes more stable.
引用
理解自动装配的优缺点是很重要的。其中优点包括:
自动装配能
显著减少配置的数量。不过,采用bean模板(见这里)也可以达到同样的目的。
自动装配可以使配置与java代码同步更新。例如,如果你需要给一个java类
增加一个依赖,那么该
依赖将被自动实现而不需要修改配置。因此强烈推荐在开发过程中采用自动装配,而在系统趋于稳定的时候改为显式装配的方式。
§3 自动装配有几种类型?
Springreference 写道
Mode Explanation
no No autowiring at all. Bean references must be defined via a ref element. This is the default,
and changing this is discouraged for larger deployments, since explicitly specifying collaborators gives
greater control and clarity. To some extent, it is a form of documentation about the structure of a system.
byName Autowiring by property name. This option will inspect the container and look for a bean named exactly
the same as the property which needs to be autowired. For example, if you have a bean definition which is
set to
autowireby name, and it contains a master property(that is, it has a setMaster(..) method),
Spring
will look for a bean definition named master, and use it to set the property.
byType Allows a property to be autowired if there is exactly one bean of the property type in the
container. If there is more than one, a fatal exception is thrown, and this indicates that you
may not use byType autowiring for that bean. If there are no matching beans, nothing
happens; the property is not set. If this is not desirable, setting the dependency-check="objects"
attribute value specifies that an error should be thrown in this case.
constructor This is analogous to byType, but applies to constructor arguments. If there isn't exactly one
bean of the constructor argument type in the container, a fatal error is raised.
autodetect Chooses constructor or byType through introspection of the bean class. If a default
constructor is found, the byType mode will be applied.
引用
模式 说明
no 默认不使用autowiring。 必须显示的使用"<ref />"标签明确地指定bean合作者,对于部署给予更大的
控制和明了。
byName 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自
动装配。例如,在bean定义中将
autowire设置为by name,而该bean包含master属性(同时提供
setMaster(..)方法),
Spring就会查找名为master的bean定义,并用它来装配给master属性。
byType 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的
bean,那么将会抛出异常,并指出不能使用byType方式进行自动装配。若没有找到相匹配的bean,
则什么事都不发生,属性也不会被设置。如果你不希望这样,那么可以通过设置
dependency-check="objects"让
Spring抛出异常。
constructor 与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类
型一致的bean,那么将会抛出异常。
autodetect 通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。
如果发现默认的构造器,那么将使用byType方式。
§4 如何启用自动装配?
你可以参照以下的配置去启用自动装配
引用
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/
spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/
spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/
spring-tx-2.5.xsd"
default-autowire="byType">
当然,这里的byType你可以更改为其他你想要的装配类型。
§5 自动装配将引发的问题?
Springreference 写道
Some disadvantages of autowiring:
• Autowiring is more magical than explicit wiring. Although, as noted in the above table,
Springis careful to
avoid guessing in case of ambiguity which might have unexpected results, the relationships between your
Spring-managed objects are no longer documented explicitly.
• Wiring information may not be available to tools that may generate documentation from a
Springcontainer.
引用
自动装配的一些缺点:
尽管自动装配比显式装配更神奇,但是,正如上面所提到的,
Spring会尽量避免在装配不明确的时候进行猜测,因为装配不明确可能出现难以预料的结果,而且
Spring所管理的对象之间的关联关系也不再能清晰的进行文档化。
对于那些根据
Spring配置文件生成文档的工具来说,自动装配将会使这些工具没法生成依赖信息。
自动装配可以减轻配置的工作量,但同时使得配置文件的可读性变得很差,因为你不可能从配置文件
中获知这些对象之间得依赖关系,从而维护困难!
注意:
当根据类型进行自动装配的时候,容器中可能存在多个bean定义跟自动装配的setter方法和构造器参数类型匹配。这样就会存在模棱两可的问题。如果bean定义不唯一,装配时就会抛出异常。
解决方案(任选其一):
1 放弃使用自动装配,使用显示装配。
2 将bean排除在自动装配之外,
引用
两个功能:
1 通过设定bean定义中的'
autowire-candidate'属性显式的设置为'true' 或 'false'来设置其是否为被自动装配
对象。
2 使用对bean名字进行模式匹配来对自动装配进行限制,其做法是在<beans/>元素的
'default-
autowire-candidates' 属性中进行设置。可以使用通配符,如以'Repository'结尾的bean,
那么可以设置为"*Repository“。
3 通过在bean定义中设置'primary'属性为'true'来将该bean设置为首选自动装配bean。
如何使用
Spring
autowire请取决于你的项目设计。