Spring IoC和DI

Spring IoC和DI

目录

IoC

引入

传统实现思路

解决方案

IoC的优势

DI


Spring 是包含了众多⼯具⽅法的 IoC 容器.

IoC

什么是IoC?

像在类上⾯添加 @RestController 和@Controller 注解, 就是把这个对象交给Spring管理, Spring 框架启动时就会加载该类. 把对象交给Spring管理, 就是IoC思想.

IoC:Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器.

什么是控制反转呢? 也就是控制权反转. 什么的控制权发⽣了反转? 获得依赖对象的过程被反转了也就是说, 当需要某个对象时, 传统开发模式中需要⾃⼰通过 new 创建对象, 现在不需要再进⾏创建, 把创建对象的任务交给容器, 程序中只需要依赖注⼊ (Dependency Injection,DI)就可以了.
这个容器称为:IoC容器. Spring是⼀个IoC容器, 所以有时Spring 也称为Spring 容器.
引入
传统实现思路

我们的实现思路是这样的:
先设计轮⼦(Tire),然后根据轮⼦的⼤⼩设计底盘(Bottom),接着根据底盘设计⻋⾝(Framework),最后根据⻋⾝设计好整个汽⻋(Car)。这⾥就出现了⼀个"依赖"关系:汽⻋依赖⻋⾝,⻋⾝依赖底盘,底盘依赖轮⼦. 

代码实现

public class Main { public static void main(String[] args) { Car car = new Car(21); car.run(); Car car2 = new Car(17); car2.run(); } } //汽车 class Car { private Framework framework; public Car(int size) { framework = new Framework(size); System.out.println("framework init..."); } public void run() { System.out.println("car run..."); } } //车身 class Framework { private Bottom bottom; public Framework(int size) { bottom = new Bottom(size); System.out.println("bottom init...."); } } //底盘 class Bottom { private Tire tire; public Bottom(int size) { tire = new Tire(size); System.out.println("tire init..."); } } //轮胎 class Tire { private int size; public Tire(int size) { System.out.println("tire size:"+size); } }

上面这样的设计看起来没问题,但是可维护性却很低,因为需求可能会越来越多,比如增加轮胎颜色,修改后的代码如下:

我们可以看到,修改后的代码会报错,并且需要我们继续修改

完整代码如下:

public class Main { public static void main(String[] args) { Car car = new Car(21,"aaa"); car.run(); Car car2 = new Car(17,"bbb"); car2.run(); } } //汽车 class Car { private Framework framework; public Car(int size,String color) { framework = new Framework(size,color); System.out.println("framework init..."); } public void run() { System.out.println("car run..."); } } //车身 class Framework { private Bottom bottom; public Framework(int size,String color) { bottom = new Bottom(size,color); System.out.println("bottom init...."); } } //底盘 class Bottom { private Tire tire; public Bottom(int size,String color) { tire = new Tire(size,color); System.out.println("tire init..."); } } //轮胎 class Tire { private int size; private String color; public Tire(int size,String color) { System.out.println("tire size:"+size); } }

从以上代码可以看出,以上程序的问题是:当最底层代码改动之后,整个调⽤链上的所有代码都需要修改.
程序的耦合度⾮常⾼(修改⼀处代码, 影响其他处的代码修改)。

解决方案

我们尝试改变实现方式:轮⼦依赖底盘, 底盘依赖⻋⾝,⻋⾝依赖汽⻋。

基于以上思路,我们把调⽤汽⻋的程序⽰例改造⼀下,把创建⼦类的⽅式,改为注⼊传递的⽅式。

完整代码如下:

class Main { public static void main(String[] args) { Tire tire = new Tire(17, "red"); Bottom bottom = new Bottom(tire); Framework framework = new Framework(bottom); Car car = new Car(framework); car.run(); } } //汽车 class Car { private Framework framework; public Car(Framework framework) { this.framework = framework; System.out.println("framework init..."); } public void run() { System.out.println("car run..."); } } //车身 class Framework { private Bottom bottom; public Framework(Bottom bottom) { this.bottom = bottom; System.out.println("bottom init...."); } } //底盘 class Bottom { private Tire tire; public Bottom(Tire tire) { this.tire=tire; System.out.println("tire init..."); } } //轮胎 class Tire { private int size; private String color; public Tire(int size, String color) { System.out.println("tire size:"+size+",color:"+color); } }

代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间的解耦,从⽽实现了更加灵活、通⽤的程序设计了。

IoC的优势

在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car

我们发现了⼀个规律,通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是使⽤⽅对象创建并控制依赖对象了,⽽是把依赖对象注⼊将当前对象中,依赖对象的控制权不再由当前类控制了.
这样的话, 即使依赖类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。

到这⾥, 我们⼤概就知道了什么是控制反转了, 那什么是控制反转容器呢, 也就是IoC容器。

这部分代码, 就是IoC容器做的⼯作.
从上⾯也可以看出来, IoC容器具备以下优点:
资源不由使⽤资源的双⽅管理,⽽由不使⽤资源的第三⽅管理,这可以带来很多好处。

第⼀,资源集中管理,实现资源的可配置和易管理。

第⼆,降低了使⽤资源双⽅的依赖程度,也就是我们说的耦合度。

1. 资源集中管理: IoC容器会帮我们管理⼀些资源(对象等), 我们需要使⽤时, 只需要从IoC容器中去取就可以了
2. 我们在创建实例的时候不需要了解其中的细节, 降低了使⽤资源双⽅的依赖程度, 也就是耦合度.

Spring 就是⼀种IoC容器, 帮助我们来做了这些资源管理. 

DI

DI: Dependency Injection(依赖注⼊)
容器在运⾏期间, 动态的为应⽤程序提供运⾏时所依赖的资源,称之为依赖注⼊。

程序运⾏时需要某个资源,此时容器就为其提供这个资源.

从这点来看, 依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦。

前面代码中, 是通过构造函数的⽅式, 把依赖对象注⼊到需要使⽤的对象中的。

IoC 是⼀种思想,也是"⽬标", ⽽思想只是⼀种指导原则,最终还是要有可⾏的落地⽅案,⽽ DI 就属于具体的实现。所以也可以说, DI 是IoC的⼀种实现.

Read more

数据库基础与MySQL核心组件解析

数据库基础与MySQL核心组件解析

—数据库专栏— 数据库基础与MySQL核心组件深度解析 * @[toc](数据库基础与MySQL核心组件深度解析) * 一、数据库基础:为什么我们需要它? * 1.1 什么是数据库? * 1.2 使用数据库的九大作用 * 二、关系型数据库与主流产品 * 2.1 关系型数据库(Relational Database)定义 * 2.1 非关系型数据库 * 2.2 主流关系型与非关系型数据库 * 三、MySQL安装与核心配置 * 3.1 MySQL 服务端程序 `mysqld` * 3.2 数据库服务器、数据库与表的关系 * 3.3 选项(配置)文件详解 * 四、MySQL客户端工具 * 五、客户端与服务器的通讯方式 * 5.1 C/

By Ne0inhk
使用Leaflet对的SpringBoot天地图路径规划可视化实践-以黄花机场到橘子洲景区为例

使用Leaflet对的SpringBoot天地图路径规划可视化实践-以黄花机场到橘子洲景区为例

目录 前言 一、路径规划需求 1、需求背景 2、技术选型 3、功能简述 二、Leaflet前端可视化 1、内容布局 2、路线展示 3、转折路线展示 三、总结 前言         在当今数字化与智能化快速发展的时代,路径规划技术已经成为现代交通管理、旅游服务以及城市规划等领域的核心工具之一。无论是日常通勤、商务出行还是旅游观光,高效、准确的路径规划都能显著提升人们的出行体验,优化资源配置,减少时间浪费和能源消耗。随着地理信息系统(GIS)技术的不断进步,结合先进的Web开发框架和地图服务,实现路径规划的可视化已经成为可能。本文旨在探讨如何利用Leaflet这一轻量级、开源的地图JavaScript库,结合Spring Boot框架和天地图服务,构建一个高效、直观的路径规划可视化系统,并以黄花机场到橘子洲景区为例,展示该技术在实际场景中的应用价值。         在之前的系列博客中,我们曾将介绍了天地图的相关开发资源,也介绍了如何在后台利用Unihttp来进行天地图的服务调用,如何将天地图返回的xml信息快速转换成json对象,但是我们仍然缺乏对转换

By Ne0inhk
实测对比:ToDesk、向日葵、AnyDesk、RustDesk、Splashtop五大主流远程软件谁最强?2026年选购指南

实测对比:ToDesk、向日葵、AnyDesk、RustDesk、Splashtop五大主流远程软件谁最强?2026年选购指南

实测对比:ToDesk、向日葵、AnyDesk、RustDesk、Splashtop五大主流远程软件谁最强?2026年选购指南 前言 最近,随着工作方式的变化,尤其是远程办公和跨设备协作的需求越来越大,我发现自己也越来越依赖远程控制软件。作为一名自由职业者,我通常在家工作,偶尔需要快速解决电脑上的一些技术问题,或者访问公司工作室的电脑进行任务处理。而在这些情况下,能够迅速、稳定地远程连接和控制另一台电脑,成了我工作的必要条件。 印象很深的一次,我正在准备一个重要的视频会议,突然遇到电脑系统卡顿,导致视频画面卡住,甚至连文件上传都出现了问题。眼看会议马上就要开始了,我急得像热锅上的蚂蚁。这时,我决定试试通过远程控制软件连接到工作室的电脑,看看能不能解决问题。 而市面上有那么多远程控制软件,究竟哪一款能够真正满足我的需求? 我的明确需求是,这款远程软件不仅要能够帮我解决突发的技术问题,还可以在不同设备之间无缝切换,尤其是能从手机、平板等移动设备上进行操作。于是,我花了一些时间,详细测试目前市场上主流的几款远程控制软件,包括ToDesk、向日葵、AnyDesk、RustDesk、

By Ne0inhk
MCP Gateway:零侵入式 API 到 MCP 协议的转换网关

MCP Gateway:零侵入式 API 到 MCP 协议的转换网关

文章目录 * 概述 * ✨ MCP Gateway 是什么? * 官网 * 核心设计理念 * 架构图 * 快速开始 * 一键启动 MCP Gateway * 访问和配置 * 测试 概述 MCP狂欢迎来了很多玩乐的MCP Server,但是也有很多产品和B端开始接入MCP,当MCP真正应用到生产环境的时候,势必会遇到大量存量的服务、API需要改造,涉及投入资源去做,因此就需要有一个MCP层面的“Nginx”来反向代理存量的API,让个人和企业可以快速接入MCP生态,快速验证想法验证市场,而不需要一开始大量effort去投入改造。 目前市场上只有Higress在支持MCP网关后迎来第二春,但是我觉得Higress并不一定适合所有人,他的接入成本略高,文档缺失,配置难以捉摸,基于istio、envoy、wasm这一套的学习成本不低,尤其希望能做一定的二开,极其痛苦。但是不可否认阿里在大规模场景下是有技术护城河的,这边只是客观描述现存问题,不拉不踩。基于这样的背景,我觉得市面上是需要存在一个更低成本、平台中立、轻量化的方案,因此我开源了这个项目,目前

By Ne0inhk