Spring系列七:Spring 自动装配

相思相见知何日?此时此夜难为情。java

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/spring/spring09.jpg

概述

Spring框架中,在配置文件中声明bean的依赖关系是一个很好的作法,由于Spring容器可以自动装配协做bean之间的关系。这称为spring自动装配。git

自动装配功能具备四种模式。分别是 nobyNamebyTypeconstructorgithub

已弃用另外一种自动连线模式自动检测。Docsautodetect选项提供了太多的magic,最好使用更明确的声明。spring

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

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/spring/spring10.png

自动装配模式

  1. no 该选项是spring框架的默认选项,表示自动装配为关闭状态OFF。咱们必须在bean定义中使用<property>标签显式设置依赖项。
  2. byName 此选项启用基于bean名称的依赖项注入。在Bean中自动装配属性时,属性名称用于在配置文件中搜索匹配的Bean定义。若是找到这样的bean,则将其注入属性。若是找不到这样的bean,则会引起错误。
  3. byType 此选项支持基于bean类型的依赖项注入。在bean中自动装配属性时,属性的类类型用于在配置文件中搜索匹配的bean定义。若是找到这样的bean,就在属性中注入它。若是没有找到这样的bean,就会引起一个错误。
  4. constructor 经过构造函数自动装配与byType类似,仅适用于构造函数参数。在启用了自动装配的bean中,它将查找构造函数参数的类类型,而后对全部构造函数参数执行自动装配类型。请注意,若是容器中没有一个彻底属于构造函数参数类型的bean,则会引起致命错误。

@Autowired 注解

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

启用注解配置
<context:annotation-config />

使用配置文件中的AutowiredAnnotationBeanPostProcessor bean定义能够实现相同的目的。微信

<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
使用@Autowired注解

如今,启用注解配置后,能够随意使用@Autowired自动链接bean依赖项。这能够经过三种方式完成:框架

@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
}
@Autowired在属性setter方法上

在属性的setter方法上使用@Autowired时,它也等效于在配置文件中经过byType进行自动装配。ui

public class EmployeeBean
{
    private DepartmentBean departmentBean;
 
    public DepartmentBean getDepartmentBean() {
        return departmentBean;
    }
 
    @Autowired
    public void setDepartmentBean(DepartmentBean departmentBean) {
        this.departmentBean = departmentBean;
    }
    //More code
}
@Autowired在构造函数上

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

package cn.howtodoinjava.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
}

@Qualifier解决冲突

咱们了解到,若是咱们在byType模式下使用自动装配,容器会在属性类类型中查找依赖项。若是找不到这样的类型,则会引起错误。可是,若是有两个或多个相同类类型的bean,该怎么办?

在这种状况下,spring将没法选择正确的bean来注入属性,所以你将须要使用@Qualifier注解来帮助容器。

要解析特定的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="cn.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
        <property name="fullName" value="Lokesh Gupta"/>
    </bean>
 
    <!--First bean of type DepartmentBean-->
    <bean id="humanResource" class="cn.howtodoinjava.autowire.constructor.DepartmentBean" >
        <property name="name" value="Human Resource" />
    </bean>
 
    <!--Second bean of type DepartmentBean-->
     <bean id="finance" class="cn.howtodoinjava.autowire.constructor.DepartmentBean" >
        <property name="name" value="Finance" />
    </bean>
</beans>

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

即便在自动装配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>

从自动装配中排除bean

默认状况下,自动装配扫描并匹配范围内的全部bean定义。若是您想排除一些bean定义,这样它们就不能经过自动装配模式被注入,可使用设置为falseautowire-candidate来作到这一点。

  1. 使用autowire-candidate做为false彻底将bean排除在自动装配候选以外。它将特定的bean定义彻底排除在自动装配基础结构以外。
    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
        <context:annotation-config />
    
        <bean id="employee" class="cn.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
            <property name="fullName" value="Lokesh Gupta"/>
        </bean>
        <!--Will be available for autowiring-->
        <bean id="humanResource" class="cn.howtodoinjava.autowire.constructor.DepartmentBean" >
            <property name="name" value="Human Resource" />
        </bean>
    
        <!--Will not participate in autowiring-->
         <bean id="finance"      class="cn.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false">
            <property name="name" value="Finance" />
        </bean>
    </beans>
  2. 另外一种方法是根据bean名称的模式匹配来限制自动装配候选对象。顶级<beans/>元素在其default-autowire-candidate属性中接受一个或多个属性。 例如,要将自动装配候选状态限制为名称以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属性的值truefalse始终优先,而对于此类bean,模式匹配规则将不适用。

这就是Spring bean自动装配的所有内容。


https://niocoder.com/assets/images/qrcode.jpg

🙂🙂🙂关注微信公众号java干货 不按期分享干货资料

原文连接:Spring Bean Autowiring – @Autowired

相关文章
相关标签/搜索