在 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