Java——Spring的控制反转(一文详解IOC)
Spring,Spring MVC,Spring Boot 三者比较
答: 这三者专注的领域不同,解决的问题也不一样;总的来说,Spring 就像一个大家族,有众多衍生产品例如 Boot,Security,JPA等等。但他们的基础都是 Spring 的 IOC 和 AOP,IOC提供了依赖注入的容器,而AOP解决了面向切面的编程,然后在此两者的基础上实现了其他衍生产品的高级功能;Spring MVC是基于 Servlet 的一个 MVC 框架,主要解决 WEB 开发的问题。与此同时, Spring 的配置非常复杂,各种xml,properties处理起来比较繁琐。于是为了简化开发者的使用,Spring社区创造性地推出了Spring Boot,它遵循约定优于配置,极大降低了Spring使用门槛,但又不失Spring原本灵活强大的功能,下面用一张图来描述三者的关系:

最后一句话总结:
Spring MVC和Spring Boot都属于Spring,Spring MVC是基于Spring的一个MVC框架,而Spring Boot是基于Spring的一套快速开发整合包
1、什么是Spring IOC容器?
答:控制反转即IOC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
Spring IOC负责创建对象,管理对象(通过依赖注入(DI),配置对象,装配对象,并且管理这些对象的整个生命周期)。
2、控制反转(IOC)有什么作用?
- 管理对象的创建和依赖关系的维护: 对象的创建并不是一件简单的事,在对象关系比较复杂时,如果依赖关系需要程序猿来维护的话,那是相当头疼的。
- 解耦: 由容器去维护具体的对象。
- 托管了类的产生过程: 比如我们需要在类的产生过程中做一些处理,最直接的例子就是代理,如果有容器程序可以把这部分处理交给容器,应用程序则无需去关心类是如何完成代理的。
3、IOC的优点是什么?
IOC或 依赖注入把应用的代码量降到最低。- 它使应用容易测试,单元测试不再需要单例和
JNDI查找机制。 - 最小的代价和最小的侵入性使松散耦合得以实现。
IOC容器支持加载服务时的饿汉式初始化和懒加载。
4、Spring IOC 的实现原理?
答: 工厂模式加反射机制。
interface Fruit {public abstract void eat();
}class Apple implements Fruit {public void eat(){System.out.println("Apple");}
}class Orange implements Fruit {public void eat(){System.out.println("Orange");}
}class Factory {public static Fruit getInstance(String ClassName) {Fruit f = null;try {f = (Fruit)Class.forName(ClassName).newInstance();} catch (Exception e) {e.printStackTrace();}return f;}
}class Client {public static void main(String[] a) {Fruit f=Factory.getInstance("spring.Apple");if(f!=null){f.eat();}}
}
5、BeanFactory 和ApplicationContext有什么区别?
答: BeanFactory和ApplicationContext 是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
5.1、依赖关系
BeanFactory: 是Spring里面最底层的接口,包含了各种Bean的定义,读取Bean配置文档,管理Bean的加载、实例化,维护Bean之间的依赖关系和控制Bean的生命周期,。ApplicationContext: 该接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:- 继承
MessageSource,因此支持国际化。 - 统一的资源文件访问方式。
- 提供在监听器中注册
Bean的事件。 - 同时加载多个配置文件。
- 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的
web层。
- 继承
5.2、加载方式
答:ApplicationContext相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
BeanFactroy:BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean()方法才会抛出异常。ApplicationContext:ApplicationContext是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例Bean,确保当你需要的时候,你就不用等待,因为它们已经创建好了。
5.3、创建方式
答: BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。
5.4、注册方式
答: BeanFactory和ApplicationContext都支持 BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory 需要手动注册,而 ApplicationContext 则是自动注册。
6、Spring 如何设计容器的,BeanFactory和ApplicationContext的关系详解?Spring控制反转(IOC)
Spring作者 Rod Johnson 设计了两个接口用以表示容器。
BeanFactoryApplicationContext
BeanFactory简单粗暴,可以理解为就是个HashMap,Key是BeanName,Value是Bean实例。通常只提供注册(put),获取(get)这两个功能。我们可以称之为 “低级容器”ApplicationContext可以称之为 “高级容器”。因为他比BeanFactory多了更多的功能。他继承了多个接口。因此具备了更多的功能。例如资源的获取,支持多种消息(例如JSP tag的支持),对BeanFactory多了工具级别的支持等待。所以你看他的名字,已经不是BeanFactory之类的工厂了,而是 “应用上下文”, 代表着整个大容器的所有功能。该接口定义了一个refresh ()方法,此方法是所有阅读 Spring 源码的人的最熟悉的方法,用于刷新整个容器,即重新加载/刷新所有的Bean。- 为了更直观的展示 “低级容器” 和 “高级容器” 的关系,这里通过常用的
ClassPathXmlApplicationContext类来展示整个容器的层级 UML 关系。
7、ApplicationContext通常的实现是什么?
FileSystemXmlApplicationContext: 此容器从一个XML文件中加载Beans的定义,XML Bean配置文件的全路径名必须提供给它的构造函数。ClassPathXmlApplicationContext: 此容器也从一个XML文件中加载Beans的定义,这里,你需要 正确设置classpath因为这个容器将在classpath里找Bean配置。WebXmlApplicationContext: 此容器加载一个XML文件,此文件定义了一个WEB应用的所有Bean。
8、什么是Spring的依赖注入?
答: 控制反转IOC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入和依赖查找。面向接口编程中,让依赖注入只需要找到符合规范的接口注入即可实现调用者和被调用者解耦。对象的调用关系由Spring管理。
- 依赖注入: 是指程序运行过程中,如果需要创建一个对象,无须再代码中
new创建,而是依赖外部的注入。Spring的依赖注入对调用者和被调用者几乎没有任何要求,完全支持对pojo之间依赖关系的管理; new对象: 类的头部进行实例化对象和依赖注入一个效果,这个时候该对象不管是否使用都贯穿该类的始终。该类对象不被回收,这个实例化对象也不会被回收。如果要使用多例对象则最好使用new创建对象而不是依赖注入,即使依赖注入有多例模式也不推荐。
9、依赖注入有什么优势?
答: 依赖注入之所以更流行是因为它是一种更可取的方式:让容器全权负责依赖查询,受管组件只需要暴露JavaBean的Setter方法或者带参数的构造器或者接口,使容器可以在初始化时组装对象的依赖关系。其与依赖查找方式相比,主要优势为:
- 查找定位操作与应用代码完全无关。
- 不依赖于容器的
API,可以很容易地在任何容器以外使用应用对象。 - 不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器。
10、有哪些不同类型的依赖注入实现方式?
答: 依赖注入是时下最流行的IOC实现方式,依赖注入分为接口注入(Interface Injection),Setter方法注入(Setter Injection)和构造器注入(Constructor Injection)三种方式。其中接口注入由于在灵活性和易用性比较差,现在从Spring4开始已被废弃。
- 构造器依赖注入: 构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂方法实例化Bean之后,调用该Bean的setter方法,即实现了基于setter的依赖注入。
构造器依赖注入和 Setter方法注入的区别
| 构造函数注入 | setter注入 |
| 没有部分注入 | 有部分注入 |
不会覆盖setter属性 | 会覆盖setter属性 |
| 任意修改都会创建一个新实例 | 任意修改不会创建一个新实例 |
| 适用于设置很多属性 | 适用于设置少量属性 |
两种依赖方式都可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依赖, setter 方法实现可选依赖。
11、Spring的循环依赖怎么理解?
答: 循环依赖是指在创建 Bean 的时候,两个为创建未完成的Bean 互相引用,形成循环。循环依赖分为三种:
- 构造器的循环依赖: 这种依赖Spring是处理不了的,直接抛出
BeanCurrentlylnCreationException异常。 - 单例模式下的
setter循环依赖: 通过 “三级缓存” 处理循环依赖。singletonObjects:一级缓存,用于保存实例化、注入、初始化完成的Bean实例;earlySingletonObjects: 二级缓存,用于保存实例化完成的Bean实例;singletonFactories:三级缓存,用于保存Bean创建工厂,以便于后面扩展有机会创建代理对象。
- 非单例循环依赖: 无法处理。

相关文章:
Java——Spring的控制反转(一文详解IOC)
Spring,Spring MVC,Spring Boot 三者比较 答: 这三者专注的领域不同,解决的问题也不一样;总的来说,Spring 就像一个大家族,有众多衍生产品例如 Boot,Security,JPA等等。…...
Android Glide限定onlyRetrieveFromCache取内存缓存submit超时阻塞方式,Kotlin
Android Glide限定onlyRetrieveFromCache取内存缓存submit超时阻塞方式,Kotlin import android.os.Bundle import android.util.Log import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import com.b…...
tinymce输入框怎么限制只输入空格或者回车时不能提交
项目场景: 项目相关背景: tinymce输入框只输入空格或者回车时提交的空数据毫无意义,所以需要限制一下 无意义的输入: 解决方案: 因为tinymce输入框传到后端的数据是代码形式,所以不能直接.trem&#…...
时间、空间复杂度的例题详解
文章前言 上篇文章带大家认识了数据结构和算法的含义,以及理解了时间、空间复杂度,那么接下来来深入理解一下时间、空间复杂度。 时间复杂度实例 实例1 // 计算Func2的时间复杂度? void Func2(int N) {int count 0;for (int k 0; k <…...
Ubuntu22.04 搭建 OpenHarmony 命令行开发环境
文章目录 简介安装工具链获取gitee源码安装编译工具编译测试 简介 在本文中,我们将介绍如何使用命令行工具在你的设备上安装OpenHarmony操作系统。OpenHarmony是一个开源的、面向物联网(IoT)设备的操作系统,它提供了一套全面的开…...
10.27 知识总结(前端)
一、 前端 1.1 什么是前端? 前端是所有跟用户直接打交道的都可以称之为是前端 比如:PC页面、手机页面、平板页面、汽车显示屏、大屏幕展示出来的都是前端内容 通俗点就是能够用肉眼看到的都是“前端” 1.2 为什么要学前端 学了前端以后我们就可以做全栈工…...
操作系统(02326)考试题库
博客主页:https://tomcat.blog.csdn.net 博主昵称:农民工老王 主要领域:Java、Linux、K8S 期待大家的关注💖点赞👍收藏⭐留言💬 目录 单选题多选题主观题 单选题 把并发进程中与共享变量有关的程序段称为…...
LeetCode题:70爬楼梯,126斐波那契数
目录 70:爬楼梯 题目要求: 解题思路:(类似斐波那契数) 递归解法: 非递归解法: 126:斐波那契数 题目要求: 解题思路: 递归解法: 非递归解…...
VTK OrientationMarker 方向 三维坐标系 相机坐标轴 自定义坐标轴
本文 以 Python 语言开发 我们在做三维软件开发时,经常会用到相机坐标轴,来指示当前空间位置; 坐标轴效果: 相机方向坐标轴 Cube 正方体坐标轴 自定义坐标轴: Code: Axes def main():colors vtkNamedC…...
工控安全与网络安全有什么不同?
在当代,全球制造业正在经历一场前所未有的技术变革。工业4.0不仅代表着自动化和数据交换的进步,它还揭示了工业自动化、智能制造与系统集成的融合。这种集成为企业带来了效率和质量的双重提升,但同时也暴露出新的安全隐患。工控系统成为了这一…...
性能测试工具:Jmeter介绍
JMeter是一个开源的Java应用程序,由Apache软件基金会开发和维护,可用于性能测试、压力测试、接口测试等。 1. 原理 JMeter的基本原理是模拟多用户并发访问应用程序,通过发送HTTP请求或其他协议请求,并测量响应时间、吞吐量、并发…...
Golang Struct 继承的深入讨论和细节
1)结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写或者小写的字段、方法,都可以使用。 type A struct {Name stringage int }func (a *A) SayName() {fmt.Println("A say name", a.Name) }func (a *A) s…...
Android11分区介绍
1.分区汇总 3566及3568分区对应如下: rockdev/Image-rk3566_rgo/ ├── boot.img ├── dtbo.img ├── MiniLoaderAll.bin ├── misc.img ├── parameter.txt ├── recovery.img ├── super.img ├── uboot.img └── vbmeta.img 2.分区说明 分区 说明 boo…...
goland无法调试问题解决
goland 无法调试问题解决 golang 版本升级后,goland 无法进行调试了 首先请看自己下载的版本是否有误 1.apple系 M系列芯片的 arm64版本 2.apple系 intel系列芯片的x86_64 3.windows系 intel解决如下: 查看gopath ericsanchezErics-Mac-mini gww-api…...
关于近期IP-Guard新版本客户端重复发送邮件的问题处理说明
关于近期新版本客户端重复发送邮件的问题处理说明 一、问题描述 近期部分客户反馈,升级到新版本的客户端(4.81.341.0、4.82.621.0及以上),使用SMTP协议发送邮件时,会出现重复发送邮件的情况,主要表现为以下两种现象: Outlook发送包含大量收件人的邮件时,收件人邮箱可能…...
linux java 启动脚本
#!/bin/sh## java env #export JAVA_HOME/data/jdk1.8.0_121 #export JRE_HOME$JAVA_HOME/jre## service name #当前目录 SERVICE_DIR$(cd dirname $0; pwd) echo "$SERVICE_DIR" #jar包路径 JAR_DIRls -ltr $SERVICE_DIR/*.jar| tail -1 echo "JAR_DIR $JAR_DI…...
Node.js 的 CommonJS ECMAScript 标准用法
目录 一、前言二、CommonJS 标准使用方法 三、ECMAScript 标准使用方法 四、常用命令总结 一、前言 本文主要是介绍 Node.js 的 CommonJS & ECMAScript 标准用法 如果对你有帮助,欢迎三连 收藏点赞关注!!! ---- NickYoung 二、…...
Mysql数据库 4.SQL语言 DQL数据查询语言 查询
DQL数据查询语言 从数据表中提取满足特定条件的记录 1.单表查询 2.多表查询 查询基础语法 select 关键字后指定要查询到的记录的哪些列 语法:select 列名(字段名)/某几列/全部列 from 表名 [具体条件]; select colnumName…...
俄罗斯黑客利用Roundcube零日漏洞窃取政府电子邮件
导语:最近,一起涉及Roundcube Webmail的零日漏洞被俄罗斯黑客组织Winter Vivern利用,攻击了欧洲政府机构和智库。这一漏洞已经存在至少一个月,直到10月16日,Roundcube开发团队才发布了安全补丁来修复这个Stored Cross-…...
【Javascript】ajax(阿甲克斯)
目录 什么是ajax? 同步与异步 原理 注意 写一个ajax请求 创建ajax对象 设置请求方式和地址 发送请求 设置响应HTTP请求状态变化的函数 什么是ajax? 是基于javascript的一种用于创建快速动态网页的技术,是一种在无需重新加载整个网页的情况下,…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
