本篇主要介绍 Spring 的依赖注入。依赖注入是 Spring 协调不同 Bean 实例之间的合作而提供的一种工作机制,在确保 Bean 实例之间合作的同时,并能保持每个 Bean 的相对独立性。通过本篇的学习,可以达成如下目标。

● 理解基于构造函数的依赖注入

● 理解基于设置函数的依赖注入

● 基于自动装配的依赖注入

● 基于注解的依赖注入

在 Spring 框架下,当 Bean 实例 A 运行过程中需要引用另外一个 Bean 实例 B 时,Spring 框架会创建 Bean 的实例 B,并将实例 B 通过实例 A 的构造函数、set 方法、自动装配和注解方式注入到实例 A,这种注入实例 Bean 到另外一个实例 Bean 的过程称为依赖注入。

在课程案例 SpringProgram 项目中,事务组件类 EmailNotice 内部引用了实体类 Teacher 类,用于向 Teacher 类发送消息,因此 EmailNotice 类依赖于 Teacher 类。Spring IOC 容器会在创建 EmailNotice 类和 Teacher 类的实例后,将 Teacher 类的实例注入到 EmailNotice 类的实例中。

依赖注入的好处就是尽可能隔离 Bean 之间的代码耦合,提高 Bean 重用的可能性,并尽量降低程序代码的维护难度。Spring 框架通过依赖注入技术将不同的 Bean 融合起来,完成复杂业务操作,但又确保了每个 Bean 相对的独立性。

Spring 框架提供了构造函数注入、设置方法注入、自动装配注入和注解注入四种注入方式,下面分别进行讨论并说明。

1、 基于构造函数的依赖注入

构造函数注入就是通过 Bean 类的构造方法,将 Bean 所依赖的对象注入。构造函数的参数一般情况下就是依赖项,spring 容器会根据 bean 中指定的构造函数参数来决定调用那个构造函数。

在课程案例 SpringProgram 项目中新建发送通知组件类 ShortNotice 类,代码如下:

ShortNotice 类依赖实体 Teacher 类,由 ShortNotice 类的构造函数注入。

在课程案例 SpringProgram 项目的 config 目录下新建 structure.xml 配置文件,配置文件代码如下:

构造注入可以传入简单值或对象类型,注入参数使用 <constructor-arg> 标签。如果注入不止一个参数时,当把参数传递给构造函数时,可能会存在歧义。要解决这个问题,就要确保在构造函数定义的参数顺序,与在配置文件中定义的注入参数顺序一致。

例如,下面的类

在配置文件需要做如下定义:

在配置文件中,也可以使用 type 属性显式指定构造函数参数的类型,容器允许使用与简单类型匹配的类型。

例如,下面的类

配置文件可以做如下定义:

另外,使用构造函数注入需要注意的是,如果需要向一个对象传递一个引用,需要使用标签的 ref 属性,如果需要直接传递值,那么应该使用如上所示的 value 属性。

2、基于设置函数的依赖注入

将 Bean 所依赖的对象通过设置函数注入,Bean 需要为注入的依赖对象提供设置方法。

在课程案例 SpringProgram 项目中,发送通知组件类 EmailNotice 依赖实体类 Teacher,向 Teacher 类发送消息。EmailNotice 类提供了设置 Teacher 类的方法,Spring IOC 容器创建 EmailNotice 和 Teacher 实例后,调用 EmailNotice 类设置 Teacher 类的方法,将 Teacher 实例注入到 EmailNotice 实例。EmailNotice 类代码如下:

EmailNotice 类有值属性和对象引用属性,值属性为 message,对象引用属性为 teacher。值属性可以通过 value 注入,对象引用属性需要通过 ref 注入。注入标签使用 <property>。配置文件代码如下。

Spring IOC 容器除了向 Bean 注入简单对象外,也可以向 Bean 注入集合对象。如 map、list、set、数组等集合对象。

在课程案例 SpringProgram 项目中新建实体类 Student,Student 类有 info 和 courses 两个属性,info 是 Map 对象,用于记录学生的基本信息,courses 是 List 对象,用于记录学生学习的课程名称。

Spring 配置文件的注入代码如下。

3、基于自动装配的依赖注入

前面讨论了基于构造函数的依赖注入和基于设置函数的依赖注入。了解了在 Spring 配置文件中使用 <constructor-arg> 和 < property > 标签注入 Bean 的依赖对象。Spring 容器还可以在不使用 < constructor-arg > 和 < property> 标签的情况下自动装配相互协作的 bean 之间的关系,这有助于减少在 Spring 配置文件中编写大量的注入语句。

Spring 的自动装配有三种模式:byType (类型模式),byName (名称模式)、constructor (构造函数模式)。

在 byType 模式中,Spring IOC 容器会基于反射查看 Bean 定义的类。当 Spring 容器发现 Bean 被设置为自动装配的 byType 模式后,它会根据参数类型在 Spring 容器中查找与参数类型相同的被依赖 Bean 对象,如果已经创建,则会把被依赖的对象自动注入到 Bean 中,如果没有创建,则不会注入。注入过程需要借助 Bean 提供的设置方法来完成,否则注入失败。

在课程案例 SpringProgram 项目中,EmailNotice 类代码如下:

EmailNotice 类依赖于 Teacher 类,并提供了设置 Teacher 类的 set 方法,可以使用 Spring 的自动装配机制。配置文件代码如下:

配置文件通过使用 <bean> 的 autowire 属性启动名称为 eamilNotice 的自动装配功能。

在 byName 模式中,Spring IOC 容器会根据定义 Bean 类的属性名称,在 Spring 容器中查找与 Bean 类属性名称相同的其它 Bean 名称进行匹配,如果找到则注入依赖 bean。

类似于 byName 和 byType 模式,constructor (构造函数模式) 适用于构造函数参数类型,Spring IOC 容器会根据定义 Bean 类的构造函数给出的参数类型,在 Spring 容器中查找与其类型相匹配的其它 Bean 类,如果找到则注入依赖 Bean。

自动装配最大的问题在于匹配失败后,Spring 容器将不会向 Bean 注入任何依赖对象,就会导致 Bean 获取不到所依赖的对象,当 Bean 使用该依赖对象时,就会发生错误。因此,在可能的情况下尽可能使用手动装配。

4、基于注解的依赖注入

前面依赖注入都需要在配置文件中手动配置,当需要配置较多 Bean 类时,需要做大量的手动部署工作,这显然不妥。在 Spring2.5 之后,Spring 增加了注解方式注入,可以解决较多 Bean 类依赖注入的问题。

Spring 主要提供了 @Autowired 和 @Resource 注解模式,下面也重点讨论这两种注解模式。

@Autowired 注解,可以对 Bean 类成员变量、方法及构造函数进行标注,完成依赖注入的自动装配工作。使用 @Autowired 可以省略 Bean 类的待依赖注入对象的 set 方法,@Autowired 默认情况下按照依赖注入对象的类型自动进行匹配。加入 @Autowired 注解的方式是在 Bean 类依赖注入对象的前面加上 @Autowired 语句。

例如,在课程案例 SpringProgram 项目中新建发送通知类 QqNotice,QqNotice 类依赖 Teacher 类,在声明 Teacher 类变量的前面加上 @Autowired 语句,代码如下:

使用注解前必须在 Spring 配置文件中注册注解驱动 <context:annotation-config/>,这样注解才能被正确识别。

使用 @Autowired 注解后,只需要在配置文件中定义 Bean 就可以了,无需再配置 Bean 之间的关联关系。

测试代码如下:

@Autowired 还提供 required 的属性,用来处理当注入的 Bean 实例不存在的情况。required 为 true 时,如果注入的 Bean 实例不存在,程序会抛出异常;required 为 false 时,如果注入的 Bean 实例不存在,程序会忽略。由于默认情况下 @Autowired 是按类型匹配的 (byType),如果需要按名称 (byName) 匹配,可以使用 @Qualifier 注解与 @Autowired 结合。

例如,修改 QqNotice 类,加入 @Qualifier 注解 @Qualifier ("teacher"),Spring 容器将会在容器中注册的所有 Bean 实例中查找名称为 “teacher” 的 Bean 实例并注入,“teacher” 为在 Spring 配置文件中定义 Bean 类的名称。

@Resource 注解的功能和 @Autowired 注解功能相近,@Resource 有 name 和 type 两个主要的属性。Spring 容器对于 @Resource 注解的 name 属性解析为 bean 的名字,type 属性则解析为 bean 的类型。因此使用 name 属性,则按 byName 模式的自动注入策略,如果使用 type 属性则按 byType 模式自动注入策略。如果两个属性都未指定,Spring 容器将通过反射技术默认按 byName 模式注入。

例如下面的注解声明:

课程小结

本文介绍了 Spring 提供的四种依赖注入方式,分别是基于构造函数的依赖注入、基于设置函数的依赖注入、基于自动装配的依赖注入、基于注解的依赖注入。

基于构造函数的依赖注入。Bean 类依赖外部类时,可以在 Bean 类内部声明该依赖类,并在提供的构造函数参数中声明该类。Spring 创建 Bean 实例时,Spring 容器会根据 Bean 中指定的构造函数参数注入外部类。

基于设置函数的依赖注入。Bean 类依赖外部类时,可以在 Bean 类内部声明该依赖类,并提供该设置该依赖类的 set 方法。Spring 容器会根据 Bean 类提供的 set 方法,将外部依赖类注入到 Bean 中。

基于自动装配的依赖注入。该模式自动装配相互协作的 bean 之间的关系,Spring 的自动装配有三种模式:byType (类型模式),byName (名称模式)、constructor (构造函数模式)。Spring 的自动装配有助于减少在 Spring 配置文件中编写大量的注入语句。

基于注解的依赖注入。在 Spring2.5 之后,Spring 增加了注解注入。当 Bean 类依赖外部类时,只要对 Bean 类所依赖的类成员变量、方法及构造函数进行标注,Spring 即可完成依赖注入的自动装配工作。

详解 Spring 框架的依赖注入相关推荐

  1. 详解Spring框架的依赖注入

    本篇主要介绍Spring的依赖注入.依赖注入是Spring协调不同Bean实例之间的合作而提供的一种工作机制,在确保Bean实例之间合作的同时,并能保持每个Bean的相对独立性.通过本篇的学习,可以达 ...

  2. 多图详解Spring框架的设计理念与设计模式

    Spring作为现在最优秀的框架之一,已被广泛的使用,51CTO也曾经针对Spring框架中的JDBC应用做过报道.本文将从另外一个视角试图剖析出Spring框架的作者设计Spring框架的骨骼架构的 ...

  3. 详解Spring框架的异步请求

    文章目录 详解Spring框架的异步请求 1.导入响应的jar包(gson) 2.前端请求 3.后端逻辑处理并返回结果 详解Spring框架的异步请求 在开发过程中有异步请求和同步请求之分. 同步请求 ...

  4. 详解spring框架入门到精通

    spring概述 spring框架的优点 spring框架的组成 spring核心IOC IOC概述 IOC入门案例 创建maven jar工程 引入spring的依赖 引入spring的核心配置文件 ...

  5. Java扫描配置文件的注解_详解Spring框架注解扫描开启之配置细节

    前言 Spring框架对Bean进行装配提供了很灵活的方式,下面归纳一下主要的方式: 在XML中进行显示配置 在Java中进行显示配置 隐式的bean发现机制和自动装配 而自动装配实现就需要注解扫描, ...

  6. 详解Spring的循环依赖

    本篇博客为学习哔哩哔哩中的黑马程序员的spring复习视频的学习笔记,仅供参考. 目录 代理的创建时机 aspectj与advisor的关系 自动后置代理处理器 循环依赖 set注入导致的循环依赖以及 ...

  7. 详解Spring框架的AOP机制

    AOP是Spring框架面向切面的编程思想,AOP采用一种称为"横切"的技术,将涉及多业务流程的通用功能抽取并单独封装,形成独立的切面,在合适的时机将这些切面横向切入到业务流程指定 ...

  8. 详解 Laravel 中的依赖注入和 IoC

    作为开发者,我们一直在尝试通过使用设计模式和尝试新的健壮型框架来寻找新的方式来编写设计良好且健壮的代码.在本篇文章中,我们将通过 Laravel 的 IoC 组件探索依赖注入设计模式,并了解它如何改进 ...

  9. laravel mysql注入_详解 Laravel 中的依赖注入和 IoC

    Laravel 作为开发者,我们一直在尝试通过使用设计模式和尝试新的健壮型框架来寻找新的方式来编写设计良好且健壮的代码.在本篇文章中,我们将通过 Laravel 的 IoC 组件探索依赖注入设计模式, ...

最新文章

  1. oracle mod结果不正确,日常问题解决记录三:记一次Win10安装Oracle11g后遇到的问题...
  2. python代码通过日期获得星期信息(根据日期获取星期day of the week)
  3. DataGrid能否动态合并一笔订单下面的多个交易
  4. 物联网串口服务器的功能和作用
  5. 计算机需要会那些英语翻译,计算机专业英语翻译
  6. sql server 中xml 数据类型的insert、update、delete
  7. Windows下安装Hadoop
  8. DQL、DML、DDL、DCL全名是啥?
  9. 云计算基础概念 笔记
  10. mysql查询结果插入另外一张表
  11. RHEL AS 5 安装MYSQL
  12. Neverland Test 2.0
  13. Latex 摘要部分
  14. 台式机连接蓝牙音响没声音 以及 声音延迟 问题解决
  15. 【USB描述符系列】二维码扫描枪
  16. matlab实现正弦内插算法(低通滤波)
  17. mysql nb3 备份_通过Navicat进行Mysql数据库自动备份与还原
  18. WEB漏洞——SQL注入之简要SQL注入
  19. 超超超 简单构造者模式
  20. android程序运行时总出现“Unfortunately,“程序名” has stopped” 的问题

热门文章

  1. 围棋AI.Sabaki+Leela+Leela Zero+AQ+Ray.2018年2月21日更新
  2. 学计算机会修网络吗,学计算机的,能帮忙修个电脑吗!
  3. iOS之UI组件整理
  4. 集群和负载均衡的简单介绍
  5. 国际汇款产品架构的演进
  6. Python 爬虫入门教程——社团授课型
  7. 新一代卡片式浏览器标签页,美观实用我都要
  8. secureCRT 把文件夹颜色字体蓝色修改为别的颜色
  9. 【Galois工具开发之路】关于类的重新装载思路
  10. Linux系统安全:安全技术和防火墙