Spring Bean 之 @Autowired 注解

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

Autowire 功能具有四种模式。这些是“ no”,“ byName”,“ byType”和“ constructor”。

autodetect不推荐使用另一种Autowire模式。Docs说,“自动检测”选项提供了太多的“魔力”,因此首选更明确的声明。

1。 Autowire Autowiring模式

如上图所示,有四种Autowiring模式,下面我们一个一个地讨论:

  1. no

    此选项是spring framework的默认选项,这意味着autowiring处于关闭状态。必须在bean定义中使用<property>标记显式地设置相关依赖项,否则的话Bean是不会Autowire的。

  2. byName

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

    更多详细信息请参考: Autowire byName example

  3. byType

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

    更多详细信息请参考 : Autowire byType example

  4. constructor

    按构造函数Autowire与按类型Autowire类似,但适用于构造函数参数。在启用了autowire的bean中,它将查找构造函数参数的类类型,然后对所有构造函数参数执行autowire bytype。请注意,如果容器中没有一个构造函数参数类型的bean,则会引发致命错误。

    更多详细信息请参考 : Autowire by constructor example

2。 @Autowired 注解

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

2.1。 配置注解

applicationContext.xml
<context:annotation-config />

使用配置文件中的autowiredannotationbeanpstprocessorbean定义也可以实现同样的功能。

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

2.2。 使用@Autowired 注解

现在,当注解配置被启用时,您可以按照自己喜欢的方式使用@Autowired来Autowire bean的依赖项。这里有三种方法:

2.2.1。 在属性上@Autowired

在属性上使用@Autowired时,它相当于配置文件中按“byType” Autowire。

EmployeeBean.java
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。 在属性的Set方法上@Autowired

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

EmployeeBean.java
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

当@Autowired用于bean的构造函数时,它也相当于配置文件中的“constructor” Autowire。

EmployeeBean.java
package com.how2codex.autowire.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 来解决Bean的冲突问题

我们了解到,如果在“byType”模式下使用Autowire ,则会查找属性类类型的依赖项。如果找不到此类类型,则引发错误。但是,如果同一类类型有两个或多个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.how2codex.autowire.constructor.EmployeeBean" autowire="constructor">
        <property name="fullName" value="Saigon"/>
    </bean>
    <!--First bean of type DepartmentBean-->
    <bean id="humanResource" class="com.how2codex.autowire.constructor.DepartmentBean" >
        <property name="name" value="Human Resource" />
    </bean>
    <!--Second bean of type DepartmentBean-->
     <bean id="finance" class="com.how2codex.autowire.constructor.DepartmentBean" >
        <property name="name" value="Finance" />
    </bean>
</beans>

4。 如何安全Autowire,“ required = false”

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

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

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

5.从Autowire 中排除bean

默认情况下,Autowire 扫描并匹配作用域中的所有bean定义。如果要排除某些bean定义,以使它们不能通过Autowire 方式注入,则可以使用设置为false的“ autowire-candidate”来实现。

  1. 使用’ autowire-candidate‘ false完全排除了bean作为Autowire 的候选对象。它将特定的bean定义完全排除在Autowire 基础结构之外。
    beans.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
        <context:annotation-config />
        <bean id="employee" class="com.how2codex.autowire.constructor.EmployeeBean" autowire="constructor">
            <property name="fullName" value="Saigon"/>
        </bean>
        <!--Will be available for autowiring-->
        <bean id="humanResource" class="com.how2codex.autowire.constructor.DepartmentBean" >
            <property name="name" value="Human Resource" />
        </bean>
        <!--Will not participate in autowiring-->
         <bean id="finance"      class="com.how2codex.autowire.constructor.DepartmentBean" autowire-candidate="false">
            <property name="name" value="Finance" />
        </bean>
    </beans>
  2. 另一个选择是基于对bean名称的模式匹配来限制Autowire 候选。顶级<beans />元素在其’ default-autowire-candidates‘属性内接受一个或多个模式。例如,要将Autowire 候选状态限制为名称以’Impl’结尾的任何bean,请提供值’* Impl’。要提供多种模式,请在以逗号分隔的列表中定义它们。
  1. beans.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <beans default-autowire-candidates="*Impl,*Dao">
        <context:annotation-config />
        <bean id="employee" class="com.how2codex.autowire.constructor.EmployeeBean" autowire="constructor">
            <property name="fullName" value="Saigon"/>
        </bean>
        <!--Will be available for autowiring-->
        <bean id="humanResource" class="com.how2codex.autowire.constructor.DepartmentBean" >
            <property name="name" value="Human Resource" />
        </bean>
        <!--Will not participate in autowiring-->
         <bean id="finance"      class="com.how2codex.autowire.constructor.DepartmentBean" autowire-candidate="false">
            <property name="name" value="Finance" />
        </bean>
    </beans>

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

这就是SpringBean的Autowire。如果你有任何疑问,请留言。

saigon has written 1445 articles

2 thoughts on “Spring Bean 之 @Autowired 注解

Leave a Reply