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
设计了两个接口用以表示容器。
BeanFactory
ApplicationContext
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的一种用于创建快速动态网页的技术,是一种在无需重新加载整个网页的情况下,…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...