spring framework 自动装配(二)

自动装配
上面说过,IOC的注入有两个地方需要提供依赖关系,一是类的定义中,二是在spring的配置中需要去描述。自动装配则把第二个取消了,即我们仅仅需要在类中提供依赖,继而把对象交给容器管理即可完成注入。
在实际开发中,描述类之间的依赖关系通常是大篇幅的,如果使用自动装配则省去了很多配置,并且如果对象的依赖发生更新我们不需要去更新配置,但是也带来了一定的缺点

spring自动装配 官方文档

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

自动装配功能具有四种模式。分别是 no,byName,byType和constructor。

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

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

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

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

使用@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进行自动装配。

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进行自动装配。

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

<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>

使用required = false进行错误安全的自动装配
即使在自动装配Bean依赖项时已格外小心,仍然可能会发现奇怪的查找失败。因此,要解决此问题,您将需要使自动装配成为可选的,以便在未找到依赖项的情况下,应用程序不应引发任何异常,而自动装配应被忽略。
这可以通过两种方式完成:
如果要使特定的bean属性的非强制性的特定bean自动装配,可以在@Autowired注解中使用required =“ false”属性。
@Autowired (required=false)
@Qualifier ("finance")
private DepartmentBean departmentBean;

如果要在全局级别(即对所有bean中的所有属性)应用可选的自动装配;使用以下配置设置。


从自动装配中排除bean
默认情况下,自动装配扫描并匹配范围内的所有bean定义。如果您想排除一些bean定义,这样它们就不能通过自动装配模式被注入,可以使用设置为false的autowire-candidate来做到这一点。

  1. 使用autowire-candidate作为false完全将bean排除在自动装配候选之外。它将特定的bean定义完全排除在自动装配基础结构之外。
<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>
2.   另一种方法是根据bean名称的模式匹配来限制自动装配候选对象。顶级<beans/>元素在其default-autowire-candidate属性中接受一个或多个属性。

例如,要将自动装配候选状态限制为名称以Impl结尾的任何bean,请提供值* Impl。要提供多种模式,请在以逗号分隔的列表中定义它们。

 <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>

请注意,bean定义的autowire-candidate属性的值true或false始终优先,而对于此类bean,模式匹配规则将不适用。
这就是Spring bean自动装配的全部内容。

posted @ 2020-10-26 18:00  浮生三月初  阅读(83)  评论(0)    收藏  举报