https://howtodoinjava.com/spring-core/spring-beans-autowiring-concepts/

在 Spring 框架中,遵循配置文件中的 bean 依赖关系是一种很好的做法,因此 Spring 容器能够自动关联 Bean 之间的关系。 这意味着可以通过检查BeanFactory的内容来自动让 Spring 为您的 bean 解决协作者(其他 bean)。 这称为 SpringBean 自动装配。

自动装配功能具有四种模式。 这些是nobyNamebyTypeconstructor

另一种自动装配模式autodetect已废弃。文档说,autodetect选项提供了太多的“魔力”,因此首选更明确的声明。

  • XML 配置中的默认自动装配模式为no
  • Java 配置中的默认自动装配模式为byType

SpringBean 自动装配 – `@Autowired` - 图1

Spring bean 自动装配模式

1. 自动装配模式

如上图所示,有五种自动装配模式。 让我们一一讨论。

  1. 没有


该选项是 spring 框架的默认选项,这意味着自动装配为OFF。 您必须使用 bean 定义中的<property>标签显式设置依赖项。

  1. 按名字


此选项启用基于 bean 名称的依赖项注入。 在 Bean 中自动装配属性时,属性名称用于在配置文件中搜索匹配的 Bean 定义。 如果找到这样的 bean,则将其注入属性。 如果找不到这样的 bean,则会引发错误。

阅读更多: 按名字自动装配示例

  1. 按类型


此选项启用基于 bean 类型的依赖项注入。 在 bean 中自动装配属性时,属性的类类型用于在配置文件中搜索匹配的 bean 定义。 如果找到这样的 bean,则将其注入属性。 如果找不到这样的 bean,则会引发错误。

阅读更多:按类型自动装配示例

  1. 构造器


constructor的自动装配与byType相似,但适用于构造函数参数。 在启用自动装配的 bean 中,它将查找构造函数参数的类类型,然后对所有构造函数参数执行自动装配bytype。 请注意,如果容器中没有一个完全属于构造函数参数类型的 bean,则会引发致命错误。

阅读更多:通过构造器示例自动装配

2. @Autowired注解

除了 bean 配置文件中提供的自动装配模式外,还可以使用@Autowired注解在 bean 类中指定自动装配。 要在 bean 类中使用@Autowired注解,必须首先使用以下配置在 spring 应用程序中启用注解。

2.1. 启用注解配置

applicationContext.xml

  1. <context:annotation-config />

使用配置文件中的AutowiredAnnotationBeanPostProcessor bean 定义可以实现相同的目的。

  1. <bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

2.2. 使用@Autowired注解

现在,启用注解配置后,您可以使用@Autowired随意地自动绑定 bean 依赖项。 这可以通过三种方式完成:

2.2.1. @Autowired属性

在属性上使用@Autowired时,等效于在配置文件中通过byType进行自动装配。

EmployeeBean.java

  1. public class EmployeeBean
  2. {
  3. @Autowired
  4. private DepartmentBean departmentBean;
  5. public DepartmentBean getDepartmentBean() {
  6. return departmentBean;
  7. }
  8. public void setDepartmentBean(DepartmentBean departmentBean) {
  9. this.departmentBean = departmentBean;
  10. }
  11. //More code
  12. }

2.2.2. 属性设置器上的@Autowired

当在设置器上使用@Autowired时,它也等效于在配置文件中通过byType进行自动装配。

EmployeeBean.java

  1. public class EmployeeBean
  2. {
  3. private DepartmentBean departmentBean;
  4. public DepartmentBean getDepartmentBean() {
  5. return departmentBean;
  6. }
  7. @Autowired
  8. public void setDepartmentBean(DepartmentBean departmentBean) {
  9. this.departmentBean = departmentBean;
  10. }
  11. //More code
  12. }

2.2.3. 构造函数上的@Autowired

在 bean 的构造函数上使用@Autowired时,它也等效于在配置文件中通过constructor自动装配。

EmployeeBean.java

  1. package com.howtodoinjava.autowire.constructor;
  2. public class EmployeeBean
  3. {
  4. @Autowired
  5. public EmployeeBean(DepartmentBean departmentBean)
  6. {
  7. this.departmentBean = departmentBean;
  8. }
  9. private DepartmentBean departmentBean;
  10. public DepartmentBean getDepartmentBean() {
  11. return departmentBean;
  12. }
  13. public void setDepartmentBean(DepartmentBean departmentBean) {
  14. this.departmentBean = departmentBean;
  15. }
  16. //More code
  17. }

3. @Qualifier解决冲突

我们了解到,如果我们在byType模式下使用自动装配,则会在依赖项中查找属性类类型。 如果找不到这样的类型,则会引发错误。 但是,如果有两个或更多相同类类型的 bean,该怎么办。

在这种情况下,spring 将无法选择正确的 bean 来注入属性,因此您将需要使用限定符来帮助容器。

要使用限定符解析特定的 bean,我们需要将@Qualifier注解与@Autowired注解一起使用,并将 bean 名称传递到注解参数中。 看看下面的例子:

EmployeeBean.java

  1. public class EmployeeBean
  2. {
  3. @Autowired
  4. @Qualifier("finance")
  5. private DepartmentBean departmentBean;
  6. public DepartmentBean getDepartmentBean() {
  7. return departmentBean;
  8. }
  9. public void setDepartmentBean(DepartmentBean departmentBean) {
  10. this.departmentBean = departmentBean;
  11. }
  12. //More code
  13. }

其中重复的 Bean 如下:

beans.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans>
  3. <context:annotation-config />
  4. <bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
  5. <property name="fullName" value="Lokesh Gupta"/>
  6. </bean>
  7. <!--First bean of type DepartmentBean-->
  8. <bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >
  9. <property name="name" value="Human Resource" />
  10. </bean>
  11. <!--Second bean of type DepartmentBean-->
  12. <bean id="finance" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >
  13. <property name="name" value="Finance" />
  14. </bean>
  15. </beans>

4. 使用required=false进行错误安全的自动装配

即使您在自动装配 Bean 依赖项时已格外小心,仍然可能会发现奇怪的查找失败。 因此,要解决此问题,您将需要使自动装配成为可选的,以便在未找到依赖项的情况下,应用程序不应引发任何异常,而自动装配应被忽略。

这可以通过两种方式完成:

  • 如果要使特定 bean 对于特定 bean 属性非强制装配,请在@Autowired注解中使用required="false"属性。
    EmployeeBean.java
    1. @Autowired (required=false)
    2. @Qualifier ("finance")
    3. private DepartmentBean departmentBean;
  • 如果要在全局级别上应用可选自动装配,即对所有 bean 中的所有属性进行应用; 使用以下配置。
    beans.xml
    1. <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
    2. <property name="requiredParameterValue" value="false" />
    3. </bean>

5. 从自动装配中排除 bean

默认情况下,自动装配扫描并匹配作用域中的所有 bean 定义。 如果要排除某些 bean 定义,以使它们无法通过自动装配方式注入,则可以使用设置为falseautowire-candidate来实现。

  1. 如果将autowire-candidate用作false,则将 bean 排除在自动装配候选之外。 它将特定的 bean 定义完全排除在自动装配基础结构之外。
    beans.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans>
    3. <context:annotation-config />
    4. <bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
    5. <property name="fullName" value="Lokesh Gupta"/>
    6. </bean>
    7. <!--Will be available for autowiring-->
    8. <bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >
    9. <property name="name" value="Human Resource" />
    10. </bean>
    11. <!--Will not participate in autowiring-->
    12. <bean id="finance" class="com.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false">
    13. <property name="name" value="Finance" />
    14. </bean>
    15. </beans>
  1. 另一个选择是在 bean 名称上基于模式匹配限制自动装配候选。 顶层的<beans />元素在其default-autowire-candidates属性中接受一个或多个模式。
    例如,要将自动装配候选状态限制为名称以Impl结尾的任何 bean,请提供值*Impl。 要提供多种模式,请在以逗号分隔的列表中定义它们。
    beans.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans default-autowire-candidates="*Impl,*Dao">
    3. <context:annotation-config />
    4. <bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
    5. <property name="fullName" value="Lokesh Gupta"/>
    6. </bean>
    7. <!--Will be available for autowiring-->
    8. <bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >
    9. <property name="name" value="Human Resource" />
    10. </bean>
    11. <!--Will not participate in autowiring-->
    12. <bean id="finance" class="com.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false">
    13. <property name="name" value="Finance" />
    14. </bean>
    15. </beans>

请注意,bean 定义的autowire-candidate属性的显式值truefalse始终优先,而对于此类 bean,模式匹配规则将不适用。

这就是 Spring bean 自动装配的全部内容。 如有疑问,请发表评论。

学习愉快!

下载源码