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

概述

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

自动装配功能具有四种模式。分别是 nobyNamebyTypeconstructor

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

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

自动装配模式

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

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

<?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自动装配的全部内容。


Spring系列七:Spring 自动装配的更多相关文章

  1. Spring系列(七) Spring MVC 异常处理

    Servlet传统异常处理 Servlet规范规定了当web应用发生异常时必须能够指明, 并确定了该如何处理, 规定了错误信息应该包含的内容和展示页面的方式.(详细可以参考servlet规范文档) 处 ...

  2. [原创]java WEB学习笔记99:Spring学习---Spring Bean配置:自动装配,配置bean之间的关系(继承/依赖),bean的作用域(singleton,prototype,web环境作用域),使用外部属性文件

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. Spring学习(六)-----Spring使用@Autowired注解自动装配

    Spring使用@Autowired注解自动装配 在上一篇 Spring学习(三)-----Spring自动装配Beans示例中,它会匹配当前Spring容器任何bean的属性自动装配.在大多数情况下 ...

  4. Spring系列之Spring常用注解总结 转载

    Spring系列之Spring常用注解总结   传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点:1.如果所有的内容都配置在.xml文件中,那么.x ...

  5. spring(4)——自动装配

    set注入和构造注入有时在做配置时比较麻烦.所以框架为了提高开发效率,提供自动装配功能,简化配置.spring框架式默认不支持自动装配的,要想使用自动装配需要修改spring配置文件中<bean ...

  6. Spring@Autowired注解与自动装配

    1   配置文件的方法 我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. Boss ...

  7. 【转】Spring@Autowired注解与自动装配

    1   配置文件的方法 我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. Boss ...

  8. Spring@Autowired注解与自动装配(转发)

    1   配置文件的方法 我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. Boss ...

  9. Spring基于的注解自动装配和依赖注入(***)

    #自动装配的小Demo: package com.gyf.annotation; //DAO层 public interface UserDao { public void save(); } pac ...

随机推荐

  1. spring boot+idea实现程序热部署

    pring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用. devtools ...

  2. codeforces700B

    CF700B Connecting Universities 题意翻译 树之王国是一个由n-1条双向路连接着n个城镇的国家,任意两个城镇间都是联通的. 在树之王国共有2k所大学坐落于不同的城镇之中. ...

  3. php框架对比

    一.ThinkPHP框架 优势:简单易用(Model,Controller,View负责各自的工作),它拥有支持XML标签库技术的编译型模版引擎,支持两种模版标签, 动态编译,缓存技术.还支持自定义标 ...

  4. AcWing:239. 奇偶游戏(前缀和 + 离散化 + 带权并查集 + 异或性质 or 扩展域并查集 + 离散化)

    小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...

  5. CF883H

    CF883H 题意: 给你一个字符串,需要把它以最小的划分次数划分为x个长度相等的回文串,可以重新排列. 解法: 大模拟一个. 分别统计出现一次的字符和出现两次的字符,如果没有出现一次的字符,那么所有 ...

  6. docker安装Elasticsearch Kibana和Cerebro

    环境:win10家庭版,基于Docker Toolbox 首先先做好以下两步准备工作: ①.打开Oracle VM VirtualBox,设置虚拟机内存大小,默认不够安装,建议如下设置: ②.启动虚拟 ...

  7. 软工-js learning

    使用教程JavaScript Standards Reference Guide-阮一峰 9.6-9.15学习进程: 1.导论 概述 JavaScript的历史 2.语法 基本语法 数据类型 数值 字 ...

  8. linux内核中的subsys_initcall是干什么的?

    注意:使用的内核源码版本为5.1.3 1. subsys_initcall长什么样子? 它其实是个宏定义,定义如下: #define subsys_initcall(fn)     __define_ ...

  9. 实体类(VO,DO,DTO)的划分

    实体类(VO,DO,DTO)的划分 (2011-12-21 15:50:27) 转载▼ 标签: it   经常会接触到VO,DO,DTO的概念,本文从领域建模中的实体划分和项目中的实际应用情况两个角度 ...

  10. svn--备忘