https://howtodoinjava.com/spring-core/spring-beans-autowiring-concepts/
在 Spring 框架中,遵循配置文件中的 bean 依赖关系是一种很好的做法,因此 Spring 容器能够自动关联 Bean 之间的关系。 这意味着可以通过检查BeanFactory的内容来自动让 Spring 为您的 bean 解决协作者(其他 bean)。 这称为 SpringBean 自动装配。
自动装配功能具有四种模式。 这些是no,byName,byType和constructor。
另一种自动装配模式autodetect已废弃。文档说,autodetect选项提供了太多的“魔力”,因此首选更明确的声明。
- XML 配置中的默认自动装配模式为
no。 - Java 配置中的默认自动装配模式为
byType。

Spring bean 自动装配模式
1. 自动装配模式
如上图所示,有五种自动装配模式。 让我们一一讨论。
该选项是 spring 框架的默认选项,这意味着自动装配为OFF。 您必须使用 bean 定义中的<property>标签显式设置依赖项。
此选项启用基于 bean 名称的依赖项注入。 在 Bean 中自动装配属性时,属性名称用于在配置文件中搜索匹配的 Bean 定义。 如果找到这样的 bean,则将其注入属性。 如果找不到这样的 bean,则会引发错误。
阅读更多: 按名字自动装配示例
此选项启用基于 bean 类型的依赖项注入。 在 bean 中自动装配属性时,属性的类类型用于在配置文件中搜索匹配的 bean 定义。 如果找到这样的 bean,则将其注入属性。 如果找不到这样的 bean,则会引发错误。
阅读更多:按类型自动装配示例
constructor的自动装配与byType相似,但适用于构造函数参数。 在启用自动装配的 bean 中,它将查找构造函数参数的类类型,然后对所有构造函数参数执行自动装配bytype。 请注意,如果容器中没有一个完全属于构造函数参数类型的 bean,则会引发致命错误。
阅读更多:通过构造器示例自动装配
2. @Autowired注解
除了 bean 配置文件中提供的自动装配模式外,还可以使用@Autowired注解在 bean 类中指定自动装配。 要在 bean 类中使用@Autowired注解,必须首先使用以下配置在 spring 应用程序中启用注解。
2.1. 启用注解配置
applicationContext.xml
<context:annotation-config />
使用配置文件中的AutowiredAnnotationBeanPostProcessor bean 定义可以实现相同的目的。
<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
2.2. 使用@Autowired注解
现在,启用注解配置后,您可以使用@Autowired随意地自动绑定 bean 依赖项。 这可以通过三种方式完成:
2.2.1. @Autowired属性
在属性上使用@Autowired时,等效于在配置文件中通过byType进行自动装配。
EmployeeBean.java
public class EmployeeBean{@Autowiredprivate DepartmentBean departmentBean;public DepartmentBean getDepartmentBean() {return departmentBean;}public void setDepartmentBean(DepartmentBean departmentBean) {this.departmentBean = departmentBean;}//More code}
2.2.2. 属性设置器上的@Autowired
当在设置器上使用@Autowired时,它也等效于在配置文件中通过byType进行自动装配。
EmployeeBean.java
public class EmployeeBean{private DepartmentBean departmentBean;public DepartmentBean getDepartmentBean() {return departmentBean;}@Autowiredpublic void setDepartmentBean(DepartmentBean departmentBean) {this.departmentBean = departmentBean;}//More code}
2.2.3. 构造函数上的@Autowired
在 bean 的构造函数上使用@Autowired时,它也等效于在配置文件中通过constructor自动装配。
EmployeeBean.java
package com.howtodoinjava.autowire.constructor;public class EmployeeBean{@Autowiredpublic EmployeeBean(DepartmentBean departmentBean){this.departmentBean = departmentBean;}private DepartmentBean departmentBean;public DepartmentBean getDepartmentBean() {return departmentBean;}public void setDepartmentBean(DepartmentBean departmentBean) {this.departmentBean = departmentBean;}//More code}
3. @Qualifier解决冲突
我们了解到,如果我们在byType模式下使用自动装配,则会在依赖项中查找属性类类型。 如果找不到这样的类型,则会引发错误。 但是,如果有两个或更多相同类类型的 bean,该怎么办。
在这种情况下,spring 将无法选择正确的 bean 来注入属性,因此您将需要使用限定符来帮助容器。
要使用限定符解析特定的 bean,我们需要将@Qualifier注解与@Autowired注解一起使用,并将 bean 名称传递到注解参数中。 看看下面的例子:
EmployeeBean.java
public class EmployeeBean{@Autowired@Qualifier("finance")private DepartmentBean departmentBean;public DepartmentBean getDepartmentBean() {return departmentBean;}public void setDepartmentBean(DepartmentBean departmentBean) {this.departmentBean = departmentBean;}//More code}
其中重复的 Bean 如下:
beans.xml
<?xml version="1.0" encoding="UTF-8"?><beans><context:annotation-config /><bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor"><property name="fullName" value="Lokesh Gupta"/></bean><!--First bean of type DepartmentBean--><bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" ><property name="name" value="Human Resource" /></bean><!--Second bean of type DepartmentBean--><bean id="finance" class="com.howtodoinjava.autowire.constructor.DepartmentBean" ><property name="name" value="Finance" /></bean></beans>
4. 使用required=false进行错误安全的自动装配
即使您在自动装配 Bean 依赖项时已格外小心,仍然可能会发现奇怪的查找失败。 因此,要解决此问题,您将需要使自动装配成为可选的,以便在未找到依赖项的情况下,应用程序不应引发任何异常,而自动装配应被忽略。
这可以通过两种方式完成:
- 如果要使特定 bean 对于特定 bean 属性非强制装配,请在
@Autowired注解中使用required="false"属性。EmployeeBean.java@Autowired (required=false)@Qualifier ("finance")private DepartmentBean departmentBean;
- 如果要在全局级别上应用可选自动装配,即对所有 bean 中的所有属性进行应用; 使用以下配置。
beans.xml<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"><property name="requiredParameterValue" value="false" /></bean>
5. 从自动装配中排除 bean
默认情况下,自动装配扫描并匹配作用域中的所有 bean 定义。 如果要排除某些 bean 定义,以使它们无法通过自动装配方式注入,则可以使用设置为false的autowire-candidate来实现。
如果将
autowire-candidate用作false,则将 bean 排除在自动装配候选之外。 它将特定的 bean 定义完全排除在自动装配基础结构之外。beans.xml<?xml version="1.0" encoding="UTF-8"?><beans><context:annotation-config /><bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor"><property name="fullName" value="Lokesh Gupta"/></bean><!--Will be available for autowiring--><bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" ><property name="name" value="Human Resource" /></bean><!--Will not participate in autowiring--><bean id="finance" class="com.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false"><property name="name" value="Finance" /></bean></beans>
另一个选择是在 bean 名称上基于模式匹配限制自动装配候选。 顶层的
<beans />元素在其default-autowire-candidates属性中接受一个或多个模式。
例如,要将自动装配候选状态限制为名称以Impl结尾的任何 bean,请提供值*Impl。 要提供多种模式,请在以逗号分隔的列表中定义它们。beans.xml<?xml version="1.0" encoding="UTF-8"?><beans default-autowire-candidates="*Impl,*Dao"><context:annotation-config /><bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor"><property name="fullName" value="Lokesh Gupta"/></bean><!--Will be available for autowiring--><bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" ><property name="name" value="Human Resource" /></bean><!--Will not participate in autowiring--><bean id="finance" class="com.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false"><property name="name" value="Finance" /></bean></beans>
请注意,bean 定义的autowire-candidate属性的显式值true或false始终优先,而对于此类 bean,模式匹配规则将不适用。
这就是 Spring bean 自动装配的全部内容。 如有疑问,请发表评论。
学习愉快!
