IOC学习笔记(上篇)

news2024/12/24 2:54:42

IOC学习笔记(上篇)

目录

  • IOC容器的职责
  • Ioc容器的实现
  • 传统IoC容器的实现
  • 依赖查找VS依赖注入
  • 构造器注入VS Setter注入
  • 面试题
    • 1. 什么是IOC?
    • 2. 依赖查找和依赖注入的区别
    • 3. Spring作为IOC容器有什么优势

学习视频地址:https://time.geekbang.org/course/detail/100042601-184049

IOC容器的职责

  • 依赖处理

    • 依赖查找
    • 依赖注入
  • 生命周期管理

    • 容器
    • 托管的资源(Java Beans 或其他资源[1])
  • 配置

    • 容器
    • 外部化配置
    • 托管的资源(Java Beans或其他资源[1:1])

      Ioc容器的实现

  • Java SE

    • Java Beans
    • Java ServiceLoader SPI[2]
    • JNDI(Java Naming and Directory Interface)
  • Java EE

    • EJB(Enterprise Java Beans)
    • Servlet
  • 开源

    • Apache Avalon(http://avalon.apache.org/closed.html)
    • PicoContainer(http://picocontainer.com)
    • Google Guice(https://github.com/google/guice)
    • Spring Framework(https://spring.io/projects/spring-framework)

      传统IoC容器的实现

  • Java Beans作为IoC容器

  • 特性

    • 依赖查找
    • 生命周期管理
    • 配置元信息
    • 事件
    • 自定义
    • 资源管理
    • 持久化
  • 规范

    • JavaBeans:https://www.oracle.com/technetwork/java/javase/tech/index-jsp-138795.html
    • BeanContext:https://docs.oracle.com/javase/8/docs/technotes/guides/beans/spec/beancontext.html

      依赖查找VS依赖注入

  • 优劣对比

构造器注入VS Setter注入

在选择构造器注入(Constructor Injection)和Setter注入(Setter Injection)之间,需要根据具体的情况来决定。 构造器注入是通过类的构造器来注入依赖对象,通常在创建对象的过程中完成注入。这种方式可以保证对象在创建完成后,其依赖关系已经完全被注入,使得对象在使用时具备完整的状态。构造器注入也可以使对象的依赖关系更加明确,减少了对于Setter方法的依赖。 Setter注入是通过类的Setter方法来注入依赖对象,通常在对象创建后通过调用Setter方法来完成注入。这种方式可以在对象创建后动态地修改其依赖关系,灵活性更高。Setter注入也可以支持可选的依赖,即某些依赖对象可以不注入而使用默认值。 选择构造器注入还是Setter注入,可以考虑以下几个方面:

  1. 对象的依赖关系是否必须要在创建时注入,还是可以在对象创建后进行注入。如果依赖关系必须在创建时注入,那么构造器注入是更合适的选择;如果依赖关系可以在创建后动态修改,那么可以考虑使用Setter注入。
  2. 对象的依赖关系是否是必需的,还是可选的。如果某些依赖是必需的,而且没有合适的默认值,那么构造器注入可以确保这些依赖在创建时被注入;如果某些依赖是可选的,可以使用Setter注入,并提供默认值。
  3. 对象的可测试性。构造器注入可以使得对象的依赖关系更加明确,方便进行单元测试,因为可以通过构造器传入模拟对象。而Setter注入在单元测试中可能需要通过反射等方式来设置依赖对象。

综上所述,选择构造器注入还是Setter注入取决于具体的情况。如果依赖关系必须在创建时注入,而且是必需的,那么构造器注入是更合适的选择;如果依赖关系可以在创建后动态修改,或者某些依赖是可选的,那么可以考虑使用Setter注入。同时,还需要考虑对象的可测试性和代码的可读性等因素。

面试题

1. 什么是IOC?

IOC,全称为Inversion of Control(控制反转),是一种软件设计原则和编程思想。它是面向对象编程(OOP)中的一种设计模式,用于解耦对象间的依赖关系。 在传统的程序设计中,对象之间的依赖关系由对象自身负责管理。例如,一个类在创建其他类的对象时,需要直接调用其他类的构造函数或方法来获取所需的对象。这种方式使得类之间紧密耦合,难以进行单元测试、代码复用和替换等操作。 而IOC是一种反转了对象创建和依赖关系管理的控制方式。在IOC中,对象的创建和依赖关系的管理由一个容器(Container)来负责。容器负责创建对象,并将依赖的对象注入到需要的地方。对象只需要定义自己所需的依赖,而不需要关心如何创建和管理这些依赖。这样可以实现对象间的解耦,提高代码的可维护性和可扩展性。 IOC的核心思想是通过依赖注入(Dependency Injection)来实现对象之间的解耦。依赖注入是指将需要的依赖对象通过构造器、Setter方法或其他方式注入到对象中,而不是由对象自己创建或获取依赖对象。依赖注入可以通过配置文件、注解或自动扫描等方式来实现。 IOC的好处包括:

  1. 解耦:IOC通过将对象的创建和依赖关系的管理交给容器来处理,使得对象之间的关系更加松散,减少了耦合。
  2. 可测试性:由于对象的依赖关系由容器注入,可以方便地进行单元测试,通过替换依赖对象来进行测试或模拟。
  3. 可扩展性:在IOC中,可以通过配置文件或注解等方式来管理对象的依赖关系,使得系统更加灵活,能够方便地进行功能扩展或替换。

常见的IOC框架包括Spring Framework、Google Guice等。这些框架提供了依赖注入的功能,可以帮助开发者实现IOC,并提供了其他的功能和工具来支持应用程序的开发。 总结来说,IOC(控制反转)是一种软件设计原则和编程思想,通过将对象的依赖关系的管理交给容器来处理,实现对象间的解耦。IOC的核心是依赖注入,将对象的依赖通过构造器、Setter方法或其他方式注入到对象中。IOC可以提高代码的可维护性、可测试性和可扩展性。

2. 依赖查找和依赖注入的区别

依赖查找(Dependency Lookup)和依赖注入(Dependency Injection)是两种不同的依赖关系管理方式。 依赖查找是指通过容器或上下文来查找所需的依赖对象。在依赖查找中,对象自己负责获取它所依赖的对象,通常是通过容器提供的方法或API来获取。例如,通过容器的getBean()方法来获取所需的对象。 依赖注入是指将依赖对象通过构造器、Setter方法或其他方式注入到对象中。在依赖注入中,对象不需要关心如何获取依赖对象,而是通过注入的方式来获取。注入可以通过配置文件、注解或自动扫描等方式实现。 区别如下:

  1. 控制方式不同:依赖查找是由对象自己控制获取依赖对象,而依赖注入是由容器控制将依赖对象注入到对象中。
  2. 依赖关系的表达方式不同:依赖查找需要在对象中显式调用容器提供的方法来获取依赖对象,而依赖注入是通过构造器、Setter方法或其他方式将依赖对象注入到对象中。
  3. 对象的可测试性不同:依赖查找在单元测试中可能需要使用模拟对象等技术来替代真实的依赖对象,而依赖注入可以通过注入不同的依赖对象来进行单元测试。
  4. 对象的依赖关系管理方式不同:依赖查找需要在每个对象中显式获取依赖对象,而依赖注入将依赖对象的管理交给容器来处理,对象只需要定义自己所需的依赖,不需要关心如何获取和管理这些依赖。

综上所述,依赖查找和依赖注入是两种不同的依赖关系管理方式。依赖查找由对象自己负责获取依赖对象,而依赖注入是由容器负责将依赖对象注入到对象中。选择依赖查找还是依赖注入取决于具体的需求和设计风格。依赖注入通常被认为是更推荐的一种方式,因为它能够实现对象间的解耦,提高代码的可维护性和可测试性。

3. Spring作为IOC容器有什么优势

Spring作为一个流行的IOC(控制反转)容器,具有以下优势:

  1. 松耦合:Spring实现了依赖注入(DI)机制,通过将对象的依赖关系交由容器管理,实现了对象间的松耦合。这使得代码更容易理解、维护和扩展,提高了系统的灵活性。
  2. 可测试性:Spring的依赖注入机制使得对象的依赖关系通过构造器、Setter方法或其他方式注入,而不是直接在对象内部创建或获取依赖对象。这样,在进行单元测试时,可以更方便地替换依赖对象,进行集成测试和模块测试。
  3. 面向接口编程:Spring鼓励面向接口编程,通过接口来定义具体类的依赖关系。这种编程方式使得代码更具扩展性和可替换性,有利于实现多态和依赖倒置原则。
  4. AOP支持:Spring提供了AOP(面向切面编程)的支持,通过配置和代理技术,可以实现横切关注点(例如事务管理、日志记录等)的集中管理和复用。这样,可以将业务逻辑与横切关注点分离,提高代码的重用性和可维护性。
  5. 生命周期管理:Spring容器管理对象的生命周期,可以在对象创建、初始化和销毁时执行相应的操作。例如,通过配置初始化方法和销毁方法,可以在对象创建和销毁时执行特定的逻辑。
  6. 配置灵活性:Spring采用基于XML、注解或Java配置的方式来进行配置,使得配置更加灵活和可扩展。可以根据具体需求选择合适的配置方式,方便地切换和修改配置,而不需要修改代码。
  7. 集成丰富:Spring提供了丰富的集成支持,可以与各种开源和商业框架进行集成,如Hibernate、MyBatis、Spring MVC等。这些集成支持简化了开发过程,提高了开发效率和系统的整合能力。

总的来说,Spring作为一个IOC容器,通过依赖注入、面向接口编程、AOP支持、生命周期管理和灵活的配置等特性,提供了优秀的开发框架和工具,使得开发者能够更加专注于业务逻辑的实现,提高了系统的可维护性、可测试性和可扩展性。


  1. 比如监听器可以通过外部引入 ↩︎↩︎
  2. 从JDK1.6版本开始引入 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/789589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

10分钟搭建链路追踪平台

随着项目越来越多,相互调用越来越复杂,搭建一个可视化的链路追踪平台显得尤为重要,今天给大家介绍的是zipkin,一个轻量级的零侵入的链路追踪平台,看我怎么10分钟给大家搭建出来。 1,介绍 zipkin官网&…

Spring6——入门

文章目录 入门环境要求构建模块程序开发引入依赖创建java类创建配置文件创建测试类运行测试程序 程序分析启用Log4j2日志框架Log4j2日志概述引入Log4j2依赖加入日志配置文件测试使用日志 入门 环境要求 JDK:Java17(Spring6要求JDK最低版本是Java17&…

简述centos7如何安装和配置nginx

Nginx(发音为"engine x")是一个开源的高性能的 Web 服务器和反向代理服务器。它具有以下特点: 高性能:Nginx 采用事件驱动的异步架构,能够处理大量并发连接而不会占用过多的系统资源。它能够轻松应对高并发访…

1156. 单字符重复子串的最大长度;1497. 检查数组对是否可以被 k 整除;1510. 石子游戏 IV

1156. 单字符重复子串的最大长度 核心思想:利用滑动窗口text[i:j),不断滑动,滑动窗口中装的是重复的单字符。枚举好窗口,然后看窗口装的字符等于多少个,如果个数小于总个数,说明我们至少可以使它增加1&…

7.25 作业

1.做一个登录界面 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {this->setFixedSize(800,600);this->setWindowOpacity(0.9);this->setWindowTitle("登录");this->setWindowIcon(QIcon("E:\\hqyj\\Qt\\icon_h…

SystemVerilog 第2章:数据类型

在 Verilog中,初学者经常分不清reg和wire两者的区别。应该使用它们中哪一个来驱动端口?连接不同模块时又该如何做? Systemverilog对经典的reg数据类型进行了改进,使得它除了作为一个变量以外,还可以被连续赋值、门单元和模块所驱动。为了与寄存器类型相区别,这种改进的数据类…

Java连锁门诊医院HIS信息管理系统源码

Java连锁门诊医院HIS信息管理系统源码:SaaS运维平台多医院多机构多门诊入驻强大的电子病历完整开发文档 一、系统概述 ❉采用主流成熟技术,软件结构简洁、代码规范易阅读,SaaS应用,全浏览器访问前后端分离,多服务协同…

RocketMQ第一课-快速实战以及集群架构搭建

一、RocketMQ产品特点 1、RocketMQ介绍 ​ RocketMQ是阿里巴巴开源的一个消息中间件,在阿里内部历经了双十一等很多高并发场景的考验,能够处理亿万级别的消息。2016年开源后捐赠给Apache,现在是Apache的一个顶级项目。 ​ 早期阿里使用Act…

【如何训练一个中译英翻译器】LSTM机器翻译模型部署(三)

系列文章 【如何训练一个中译英翻译器】LSTM机器翻译seq2seq字符编码(一) 【如何训练一个中译英翻译器】LSTM机器翻译模型训练与保存(二) 【如何训练一个中译英翻译器】LSTM机器翻译模型部署(三) 目录 系列…

通过两种实现方式理解CANoe TC8 demo是如何判断接收的以太网报文里的字段的

假设有一个测试用例,需求是:编写一个测试用例,发送一条icmpv4 echo request报文给DUT,identifier字段设置为10。判断DUT能够回复icmpv4 echo reply报文,且identifier字段值为10。 实现:在canoe的simulation setup界面插入一个test节点,ip地址为:192.168.0.1,mac地址为…

Tensorflow学习

一、处理数据的结构 案例代码如下: import tensorflow.compat.v1 as tf tf.disable_v2_behavior() import numpy as np# create data x_data np.random.rand(100).astype(np.float32) y_data x_data*0.1 0.3# 创建结构(一维结构) Weights tf.Variable(tf.random.uniform(…

数据结构-顺序表各项功能的实现

文章目录 前言一、"SeqList.h"部分二、"SeqList.c"部分1.初始化2.销毁3.扩容及打印4.尾插及尾删5.头插及头删6.顺序表查找7.顺序表在pos位插入x8.顺序表删除low位置的数 三、"text.c"部分结语 前言 线性表是n个具有相同属性的有限数列&#xff0…

基于VUE3+Layui从头搭建通用后台管理系统(前端篇)五:后台主页功能实现上

一、本章内容 本章实现后台主页框架实现、菜单的动态加载及生产、tab组件与菜单绑定、菜单与路由绑定等,工具栏按钮等界面及对应功能实现。 1. 详细课程地址: 待发布 2. 源码下载地址: 待发布 二、界面预览

(六)springboot实战——springboot的启动流程分析

前言 本节内容我们主要介绍一下springboot的启动流程,它内部是如何实现启动加载的,启动过程中都做了哪些工作,这是我们比较关注的问题。 正文 SpringBootApplication启动类注解的解读 - SpringBootConfiguration:等同于Configu…

WPF实战学习笔记09-创建工作单元

创建工作单元 添加包 Microsoft.EntityFrameworkCore.AutoHistory A plugin for Microsoft.EntityFrameworkCore to support automatically recording data changes history. Microsoft.EntityFrameworkCore.UnitOfWork A plugin for Microsoft.EntityFrameworkCore to suppor…

【Docker 实用技巧】动态切换国内外源

目录 前言: 1、背景 2、ChatGPT 的方案 3、我的方案 3.1 本地构建 3.2 Github Action 构建 3.3 实际方案 前言: Docker 是一个非常流行的开发和部署平台,它可以帮助开发者快速构建、部署和管理应用程序。在使用 Docker 的过程中&…

聊聊STM32 ADC的话题

STM32 微控制器系列提供了多个模拟数字转换器(ADC)模块,用于实现模拟信号的采集和转换为数字信号。ADC 在很多应用中都是非常重要的,例如传感器数据采集、电压测量等。 在 STM32 中,ADC 可以通过 STM32HAL 库提供的函…

Unity游戏源码分享-3d机器人推箱子游戏

Unity游戏源码分享-3d机器人推箱子游戏 一个非常意思的3D游戏 工程地址:https://download.csdn.net/download/Highning0007/88098014

leetcode5. 最长回文子串(Manacher - java)

Manacher回文算法 leetcode5. 最长回文子串Manacher 算法 manacher 算法 leetcode5. 最长回文子串 给你一个字符串 s,找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。 示例 1: 输入:s “…

pear文件利用 (远程文件下载、生成配置文件、写配置文件) 从一道题看——CTFshow私教 web40

web40 考点:pear文件包含 pear是PHP的一个扩展 条件: 1 有文件包含点 2 开启了pear扩展 (可以当他是一个框架) 3 配置文件中register_argc_argv 设置为On,而默认为Off($_SERVER[‘argv’]生效) 4 找到…