当前位置: 首页 > news >正文

JavaEE进阶学习:Spring核心和设计思想

Spring 是什么

我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃而庞大的社区,这就是它之所以能长久不衰的原因。Spring 支持广泛的应用场景,它可以让 Java 企业级的应用程序开发起来更简单。

用⼀句话概括 Spring:Spring 是包含了众多工具方法IoC 容器

1.什么是容器

容器是用来容纳某种物品的(基本)装置。

我们学过的容器:
List/Map -> 数据存储容器
Tomcat -> Web 容器

2.什么是 IoC

Spring 也是⼀个容器,Spring 是什么容器呢?Spring 是⼀个 IoC 容器。

什么是 IoC?
IoC = Inversion of Control 翻译成中文是“控制(权)反转”的意思,也就是说 Spring 是⼀个“控制反转”的容器

控制(权)反转
对象的生命周期是由当前代码 / 程序员来控制的,当用了 Spring 时,就会由 Spring (Spring 容器)控制

Ioc 的优势
可以实现解耦(松耦合)

我们举 car 的例子来解释:
在这里插入图片描述

构建一辆车(Car Class),然而车需要依赖车身(FrameWork Class),而车身需要依赖底盘(BottomClass),而底盘需要依赖轮胎(Tire Class)

package old;/*** @projectName: test-2023-11-13* @package: old* @className: car* @author: 王嘉辉* @description:* @date: 2023/11/13 17:04* @version: 1.0*//*** 传统的开发*/
public class Car {//车身private FrameWork framework;public Car() {this.framework = new FrameWork();}public void init() {System.out.println("执行了 Car init 方法");framework.init();}
}
package old;/*** @projectName: test-2023-11-13* @package: old* @className: FrameWork* @author: 王嘉辉* @description:* @date: 2023/11/13 18:57* @version: 1.0*/
public class FrameWork {private Bottom bottom;public FrameWork() {this.bottom = new Bottom();}public void init() {System.out.println("执行了 FrameWork init 方法");bottom.init();}
}
package old;/*** @projectName: test-2023-11-13* @package: old* @className: Bottom* @author: 王嘉辉* @description:* @date: 2023/11/13 19:00* @version: 1.0*/
public class Bottom {private Tire tire;public Bottom() {this.tire = new Tire();}public void init() {System.out.println("执行了 Bottom init 方法");tire.init();}
}
package old;/*** @projectName: test-2023-11-13* @package: old* @className: Tire* @author: 王嘉辉* @description:* @date: 2023/11/13 19:01* @version: 1.0*/
public class Tire {private int size = 15;public void init() {System.out.println("执行了Tire init. Size: " + size);}
}
package old;/*** @projectName: test-2023-11-13* @package: old* @className: Test* @author: 王嘉辉* @description:* @date: 2023/11/13 19:04* @version: 1.0*/
public class Test {public static void main(String[] args) {Car car = new Car();car.init();}
}

我们需要加工多种尺寸的轮胎,就要对上述代码进行修改

package old;/*** @projectName: test-2023-11-13* @package: old* @className: car* @author: 王嘉辉* @description:* @date: 2023/11/13 17:04* @version: 1.0*//*** 传统的开发*/
public class Car {//车身private FrameWork framework;public Car(int size) {this.framework = new FrameWork(size);}public void init() {System.out.println("执行了 Car init 方法");framework.init();}
}
package old;/*** @projectName: test-2023-11-13* @package: old* @className: FrameWork* @author: 王嘉辉* @description:* @date: 2023/11/13 18:57* @version: 1.0*/
public class FrameWork {private Bottom bottom;public FrameWork(int size) {this.bottom = new Bottom(size);}public void init() {System.out.println("执行了 FrameWork init 方法");bottom.init();}
}
package old;/*** @projectName: test-2023-11-13* @package: old* @className: Bottom* @author: 王嘉辉* @description:* @date: 2023/11/13 19:00* @version: 1.0*/
public class Bottom {private Tire tire;public Bottom(int size) {this.tire = new Tire(size);}public void init() {System.out.println("执行了 Bottom init 方法");tire.init();}
}
package old;/*** @projectName: test-2023-11-13* @package: old* @className: Tire* @author: 王嘉辉* @description:* @date: 2023/11/13 19:01* @version: 1.0*/
public class Tire {private int size = 15;public Tire(int size) {this.size = size;}public void init() {System.out.println("执行了Tire init. Size: " + size);}
}
package old;/*** @projectName: test-2023-11-13* @package: old* @className: Test* @author: 王嘉辉* @description:* @date: 2023/11/13 19:04* @version: 1.0*/
public class Test {public static void main(String[] args) {Car car = new Car(20);car.init();}
}

当最底层代码改动之后,整个调用链上的所有代码都需要修改。

我们使用IoC解耦
在这里插入图片描述

package ioc;/*** @projectName: test-2023-11-13* @package: ioc* @className: Car* @author: 王嘉辉* @description:* @date: 2023/11/13 19:56* @version: 1.0*/
public class Car {private FrameWork frameWork;public Car(FrameWork frameWork) {this.frameWork = frameWork;//frameWork = new FrameWork();}public void init() {System.out.println("Car init");frameWork.init();}
}
package ioc;/*** @projectName: test-2023-11-13* @package: ioc* @className: FrameWork* @author: 王嘉辉* @description:* @date: 2023/11/13 20:00* @version: 1.0*/
public class FrameWork {private Bottom bottom;public FrameWork(Bottom bottom) {this.bottom = bottom;}public void init() {System.out.println("FrameWork init ");bottom.init();}
}
package ioc;/*** @projectName: test-2023-11-13* @package: ioc* @className: Bottom* @author: 王嘉辉* @description:* @date: 2023/11/13 20:01* @version: 1.0*/
public class Bottom {private Tire tire;public Bottom(Tire tire) {this.tire = tire;}public void init() {System.out.println("Bottom init");tire.init();}
}
package ioc;/*** @projectName: test-2023-11-13* @package: ioc* @className: Tire* @author: 王嘉辉* @description:* @date: 2023/11/13 20:02* @version: 1.0*/
public class Tire {private int size = 15;public Tire() {}public void init() {System.out.println("Tire init. Size: " + size);}
}
package ioc;/*** @projectName: test-2023-11-13* @package: ioc* @className: Test* @author: 王嘉辉* @description:* @date: 2023/11/13 20:03* @version: 1.0*//*** 模拟Ioc*/
public class Test {private Tire tire;private Bottom bottom;private FrameWork frameWork;private Car car;public Test() {this.tire = new Tire();this.bottom = new Bottom(this.tire);this.frameWork = new FrameWork(this.bottom);this.car = new Car(this.frameWork);}public static void main(String[] args) {Test test = new Test();test.car.init();}
}

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

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

通用程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了Framework,Framework 创建并创建了 Bottom,依次往下,而改进之后的控制权发生的反转,不再是上级对象创建并控制下级对象了,而是下级对象把注入将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发生任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。

相关文章:

  • uniapp中在组件中使用被遮挡或层级显示问题
  • 大模型深入发展,数字化基础设施走向“算粒+电粒”,双粒协同
  • 微信公众号制作的资源及网站分享!
  • Azure 机器学习 - 使用受保护工作区时的网络流量流
  • APP攻防-资产收集篇反证书检验XP框架反代理VPN数据转发反模拟器
  • 大数据之LibrA数据库系统告警处理(ALM-12035 恢复任务失败后数据状态未知)
  • odoo16前端框架源码阅读——boot.js
  • ChinaSoft 论坛巡礼|开源软件供应链论坛
  • 酷柚易汛ERP - 序列号状态表操作指南
  • Swift 常用类别整理
  • [P7885][Android13] 解决5G信号良好状态栏信号只有两格的问题
  • CI/CD简介
  • 关于lumen严格模式接口mysql5.6和mysql5.7报错问题
  • 13.利用辗转相除法求两个整数的最大公约数和最小公倍数。如96,36
  • 常见面试题-计算机网络相关
  • @angular/forms 源码解析之双向绑定
  • 03Go 类型总结
  • Android优雅地处理按钮重复点击
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • JSDuck 与 AngularJS 融合技巧
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • Mocha测试初探
  • React-Native - 收藏集 - 掘金
  • SpingCloudBus整合RabbitMQ
  • sublime配置文件
  • Twitter赢在开放,三年创造奇迹
  • windows下mongoDB的环境配置
  • 分布式熔断降级平台aegis
  • 马上搞懂 GeoJSON
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 深入浏览器事件循环的本质
  • 推荐一个React的管理后台框架
  • UI设计初学者应该如何入门?
  • 阿里云服务器如何修改远程端口?
  • #define、const、typedef的差别
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (三)模仿学习-Action数据的模仿
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .NET CLR Hosting 简介
  • .NetCore部署微服务(二)
  • .NET实现之(自动更新)
  • @Service注解让spring找到你的Service bean
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)
  • [BZOJ 3282] Tree 【LCT】
  • [BZOJ1040][P2607][ZJOI2008]骑士[树形DP+基环树]
  • [EFI]MSI GF63 Thin 9SCXR电脑 Hackintosh 黑苹果efi引导文件
  • [FFmpeg学习]从视频中获取图片
  • [HNOI2006]鬼谷子的钱袋
  • [LeetCode] NO. 169 Majority Element
  • [LeetCode]284. Peeking Iterator(C++,类,暴力)
  • [Nginx]反向代理Node将3000端口访问转换成80端口
  • [python]使用pyqt5搭建yolov8 竹签计数一次性筷子计数系统