Spring5核心原理-Bean 自动装配和@Autowired注解

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

对于最新的 String 版本,我们应该使用基于注解的 Spring 配置。

自动装配功能有四种模式。它们是' no'、' byName'、' byType'和' constructor'。

另一种自动连线模式autodetect已被弃用。Docs 说“自动检测”选项提供了太多的“魔力”,因此首选更明确的声明。

  • XML 配置中的默认自动装配模式no.
  • java 配置中的默认自动装配模式byType.
四种加载模式
四种加载(装配)模式

1.自动装配模式

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

No

此选项是 spring 框架的默认选项,这意味着自动装配是关闭的。 您必须在 bean 定义中使用 <property> 标记显式设置依赖关系。

byName

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

byType

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

constructor

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

2.@Autowired注解

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

2.1. 启用注释配置

<context:annotation-config />

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

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

2.2. 使用@Autowired 注解

现在,启用注解配置后,您可以按照自己喜欢的方式使用 @Autowired 自由地自动装配 bean 依赖项。 这是通过三种方式完成的:

2.2.1. @Autowired 通过属性完成装载

在属性上使用@Autowired 时,相当于通过配置文件中的‘byType’自动装配。

public class EmployeeBean
{
    @Autowired
    private DepartmentBean departmentBean;
 
    public DepartmentBean getDepartmentBean() {
        return departmentBean;
    }
    public void setDepartmentBean(DepartmentBean departmentBean) {
        this.departmentBean = departmentBean;
    }
  //More code
}
2.2.2. @Autowired 通过属性的setters方法

在 setter 上使用 @Autowired 时,也相当于通过配置文件中的“byType”进行自动装配。

public class EmployeeBean
{
    private DepartmentBean departmentBean;
 
    public DepartmentBean getDepartmentBean() {
        return departmentBean;
    }
 
  @Autowired
    public void setDepartmentBean(DepartmentBean departmentBean) {
        this.departmentBean = departmentBean;
    }
  //More code
}

2.2.3. @Autowired 在构造函数上
当在bean的构造函数上使用@Autowired时,也相当于配置文件中的‘constructor’自动装配.

public class EmployeeBean
{
    @Autowired
    public 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 名称。 看看下面的例子:

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如下:

<?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 进行自动装配,这样如果找不到这些依赖项,应用程序就不会抛出任何异常。

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

如果您想让特定 bean 自动装配对特定 bean 属性是非强制性的,请在 @Autowired 注释中使用 required=”false” 属性。

@Autowired (required=false)
@Qualifier ("finance")
private DepartmentBean departmentBean;

如果您想在全局级别应用可选的自动装配,即适用于所有 bean 中的所有属性; 使用以下配置设置。

<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 定义。

<?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”。 要提供多种模式,请在逗号分隔的列表中定义它们。

<?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,模式匹配规则将不适用。
 

原创文章,作者:端木书台,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/243951.html

(0)
上一篇 2022年4月11日 22:21
下一篇 2022年4月11日 22:21

相关推荐

发表回复

登录后才能评论