Autowiring Collaborators
Spring 容器可以自动连接协作 Bean 之间的关系。你可以让 Spring 通过检查 ApplicationContext
的内容自动为你的 Bean 解析协作者(其他 Bean)。自动连接有以下优点:
The Spring container can autowire relationships between collaborating beans. You can
let Spring resolve collaborators (other beans) automatically for your bean by
inspecting the contents of the ApplicationContext
. Autowiring has the following
advantages:
-
Autowiring can significantly reduce the need to specify properties or constructor arguments. (Other mechanisms such as a bean template discussed elsewhere in this chapter are also valuable in this regard.)
-
Autowiring can update a configuration as your objects evolve. For example, if you need to add a dependency to a class, that dependency can be satisfied automatically without you needing to modify the configuration. Thus autowiring can be especially useful during development, without negating the option of switching to explicit wiring when the code base becomes more stable.
当使用基于 XML 的配置元数据(请参阅 Dependency Injection)时,你可以使用 `<bean/>`元素的 `autowire`属性为 bean 定义指定自动连接模式。自动连接功能有四种模式。你可以针对每个 bean 指定自动连接,因此可以自行选择要自动连接哪些 bean。下表描述了四种自动连接模式:
When using XML-based configuration metadata (see Dependency Injection), you
can specify the autowire mode for a bean definition with the autowire
attribute of the
<bean/>
element. The autowiring functionality has four modes. You specify autowiring
per bean and can thus choose which ones to autowire. The following table describes the
four autowiring modes:
Mode | Explanation |
---|---|
|
(Default) No autowiring. Bean references must be defined by |
|
Autowiring by property name. Spring looks for a bean with the same name as the
property that needs to be autowired. For example, if a bean definition is set to
autowire by name and it contains a |
|
Lets a property be autowired if exactly one bean of the property type exists in
the container. If more than one exists, a fatal exception is thrown, which indicates
that you may not use |
|
Analogous to |
通过 byType
或者 constructor
的自动装配模式,你可以连接数组和类型化集合。在这种情况下,容器内符合预期类型的所有自动装配候选都将提供,以便满足依赖关系。如果预期键类型是 String
,你可以自动装配强类型化的 Map
实例。自动装配的 Map
实例的值包含与预期类型相符的所有 Bean 实例,而 Map
实例的键则包含相应的 Bean 名称。
With byType
or constructor
autowiring mode, you can wire arrays and
typed collections. In such cases, all autowire candidates within the container that
match the expected type are provided to satisfy the dependency. You can autowire
strongly-typed Map
instances if the expected key type is String
. An autowired Map
instance’s values consist of all bean instances that match the expected type, and the
Map
instance’s keys contain the corresponding bean names.
Limitations and Disadvantages of Autowiring
在整个项目中一致使用自动装配时,效果最佳。如果一般不使用自动装配,只有在连接一个或两个 Bean 定义时使用自动装配,这可能会让开发者感到困惑。
Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing to developers to use it to wire only one or two bean definitions.
考虑自动装配的局限性和缺点:
Consider the limitations and disadvantages of autowiring:
-
Explicit dependencies in
property
andconstructor-arg
settings always override autowiring. You cannot autowire simple properties such as primitives,Strings
, andClasses
(and arrays of such simple properties). This limitation is by-design. -
Autowiring is less exact than explicit wiring. Although, as noted in the earlier table, Spring is careful to avoid guessing in case of ambiguity that 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 Spring container.
-
Multiple bean definitions within the container may match the type specified by the setter method or constructor argument to be autowired. For arrays, collections, or
Map
instances, this is not necessarily a problem. However, for dependencies that expect a single value, this ambiguity is not arbitrarily resolved. If no unique bean definition is available, an exception is thrown.
在后一种情况下,你可以选择诸多选项:
In the latter scenario, you have several options:
-
Abandon autowiring in favor of explicit wiring.
-
Avoid autowiring for a bean definition by setting its
autowire-candidate
attributes tofalse
, as described in the next section. -
Designate a single bean definition as the primary candidate by setting the
primary
attribute of its<bean/>
element totrue
. -
Implement the more fine-grained control available with annotation-based configuration, as described in Annotation-based Container Configuration.
Excluding a Bean from Autowiring
根据每个 bean,你可以将 bean 排除在自动连接之外。在 Spring 的 XML 格式中,将 <bean/>`元素的 `autowire-candidate`属性设置为 `false
。容器会使该特定的 bean 定义对自动连接基础设施不可用(包含注释样式的配置,例如 @Autowired
)。
On a per-bean basis, you can exclude a bean from autowiring. In Spring’s XML format, set
the autowire-candidate
attribute of the <bean/>
element to false
. The container
makes that specific bean definition unavailable to the autowiring infrastructure
(including annotation style configurations such as @Autowired
).
|
The |
你还可以根据 Bean 名称的模式匹配限制自动装配候选。顶级 <beans/>
元素在其 default-autowire-candidates
特性中接受一个或多个模式。例如,要将自动装配候选的状态限制为名称以 Repository
结尾的任何 Bean,请提供 *Repository
值。要提供多个模式,请在逗号分隔列表中定义它们。Bean 定义的 autowire-candidate
特性的明确 true
或 false
值始终优先。对于此类 Bean,模式匹配规则不适用。
You can also limit autowire candidates based on pattern-matching against bean names. The
top-level <beans/>
element accepts one or more patterns within its
default-autowire-candidates
attribute. For example, to limit autowire candidate status
to any bean whose name ends with Repository
, provide a value of *Repository
. To
provide multiple patterns, define them in a comma-separated list. An explicit value of
true
or false
for a bean definition’s autowire-candidate
attribute always takes
precedence. For such beans, the pattern matching rules do not apply.
这些技术对于你永远不想通过自动装配注入到其他 Bean 中的 Bean 非常有用。这并不意味着无法通过使用自动装配来自身配置被排除的 Bean。相反,Bean 本身不适合于自动装配其他 Bean。
These techniques are useful for beans that you never want to be injected into other beans by autowiring. It does not mean that an excluded bean cannot itself be configured by using autowiring. Rather, the bean itself is not a candidate for autowiring other beans.