Spring框架技术的核心与设计思想

news2025/1/17 0:14:58

目录

1. Spring 是什么?

1.1 什么是容器? 

1.2 什么是 IoC ?

2. 传统式开发

3. 控制(权)反转式开发

4. 理解Spring 核心 - IoC


1. Spring 是什么?

Spring 的全称是 Spring Framework, 它是一种开源框架, 2002 年, Rod Jahnson 首次推出了 Spring 框雏形 interface21 框架.  两年后, Spring 框架以 interface21 框架为基础, 经过重新设计, 发布了 1.0 正式版....给软件行业带来了春天!!

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

1.1 什么是容器? 

所谓容器, 通俗来说就是容纳某种物品的装置, 在学数据结构的时候, 我们的各种集合就叫做容器, 例如 List, Map 等等用于存储数据的这些集合不就是一种容器吗, 还有我们在学 Sevlet 的时候, 用到的 Tomcat 也是一个容器, 它是用来存放每一个 Web 项目的.

1.2 什么是 IoC ?

说 Spring 是一个 IoC 容器, 那什么又是 IoC 呢 ? 

IoC 全称 -> Inversion of COntrol , 翻译成中文就是 "控制(权)反转的意思" !

>> 如何理解控制(权)反转? 

简言之就是把控制权交给别人了, 自己不需要管了.

>> 控制(权)反转了, 是否就意味着自己不能控制了? 

控制(权)反转后, 自己还是可以通过一些手段来进行控制, 但是没有必要. 这就好比我们的手动挡的车和自动挡的车, 在没有自动挡的时代, 我们需要踩离合, 手动挂挡, 拉手刹等等操作, 这些操作都由我们自己控制; 当有了自动挡之后, 我们就可以把控制权交给发动机, 交给引擎来控制,  此时你还会想要自己去控制吗, 完全没有必要...

说一千道一万, 什么是 "控制反转" , 好像还是没有说太明白, 接下来我们通过 "传统式开发"  和 "控制(权)反转式开发" 二者的代码对比来进行理解!!

2. 传统式开发

假如现在我们想要造一辆汽车, 造汽车依赖于车身, 造车身又依赖于底盘, 造底盘又依赖于轮胎.....

【代码示例】

2.1 Class 汽车

public class Car {
    private Framework framework;
    
    public Car() {
        framework = new Framework();
    }
    public static void main(String[] args) {
        // 构建并启动一辆车
        Car car = new Car();
        car.init();
    }
    // 运行
    public void init() {
        System.out.println("Car init.");
        // 依赖于车身 -> framework -> init()
        framework.init();
    }
}

2.2 Class 车身

public class Framework {
    private Bottom bottom;

    public Framework() {
        bottom = new Bottom();
    }
    public void init() {
        System.out.println("Framework init.");
        // 依赖于底盘 -> bottom -> init()
        bottom.init();
    }
}

2.3 Class 底盘

public class Bottom {
    private Tire tire;

    public Bottom() {
        tire = new Tire();
    }
    public void init() {
        System.out.println("Bottom init.");
        // 依赖于轮胎 -> tire -> init()
        tire.init();
    }
}

2.4 Class 轮胎

public class Tire {
    // 尺寸
    private int size = 16;

    public void init() {
        System.out.println("Tire size:" + size);
    }
}

在传统时代, 假设人们都只需要车轮大小为 16 尺寸的汽车, 此时产品经理就告诉生产线上的负责人说造 16 尺寸的轮胎就行了, 随着物质水平的提高, 人们个性化追求是必然的趋势, 有些人就可能不满足于只有 16 尺寸轮胎的汽车, 这时候就需要修改代码, 给轮胎类中的构造方法加一个 size 参数, 你想要多大尺寸的轮胎, 你传给我就好了, 接下来看代码: 

public class Tire {
    // 尺寸
    private int size = 16;

    public Tire(int size) {
        this.size = size;
    }

    public void init() {
        System.out.println("Tire size:" + size);
    }
}

>>当我给轮胎的构造方法中加上一个参数之后, 前面有着依赖关系的底盘代码就报错了, 并且整个依赖链上的所有代码都需要做出改变,  这就是传统开发的问题所在了. 代码的耦合性太强.这还只是四层调用关系的代码, 并且只修改了一个参数, 如果是十几层调用关系的代码, 并且修改多个参数, 可想而知通过传统的方式传参的问题有多大了.

>>当客户的需求越来越多时, 我该如何解决: 

我们可以将控制权交给别人, 也就是相当于把轮胎, 车身, 以及其他部分外包给别人来做,  我们就不用再去关心客户的这些多种多样的需求了. 只需要向代理厂商下订单就好了. 所以就需要用到控制(权)反转式开发.

3. 控制(权)反转式开发

这种方式的开发, 传递的参数就不再是轮胎的尺寸, 材质以及车身的颜色, 而是直接将整个轮胎对象当做参数进行传递, 轮胎, 车身怎么变化我不再关心了, 控制权我交给厂商.

【代码示例】 

App(测试代码)

public class App {
    public static void main(String[] args) {
        // 程序调用
        int size = 17;
        String color = "黑色";
        String wood = "铝合金";
        TireV2 tireV2 = new TireV2(size, color, wood);
        BottomV2 bottomV2 = new BottomV2(tireV2);
        FrameworkV2 frameworkV2 = new FrameworkV2(bottomV2);
        CarV2 carV2 = new CarV2(frameworkV2);
        carV2.init();
    }
}

3.1 Class 汽车

public class CarV2 {
    private FrameworkV2 frameworkV2;

    public CarV2(FrameworkV2 frameworkV2) {
        // frameworkV2 = new FrameworkV2(); // 舍弃自己创建车身这种写法
        this.frameworkV2 = frameworkV2; // 控制权交给别了
    }
    public void init() {
        System.out.println("Car v2 init.");
        // 依赖于车身 -> frameworkV2 -> init()
        frameworkV2.init();
    }
}

3.2 Class 车身

public class FrameworkV2 {

    private BottomV2 bottomV2;

    public FrameworkV2(BottomV2 bottomV2) {
        this.bottomV2 = bottomV2;
    }
    public void init() {
        System.out.println("Framework v2 init.");
        // 依赖于底盘 -> bottomV2 -> init()
        bottomV2.init();
    }
}

3.3 Class 底盘 

public class BottomV2 {
    private TireV2 tireV2;
    public BottomV2(TireV2 tireV2) {
        this.tireV2 = tireV2;
    }
    public void init() {
        System.out.println("Bottom V2 init.");
        // 依赖于轮胎 -> tireV2 -> init()
        tireV2.init();
    }
}

3.4 Class 轮胎

public class TireV2 {
    private int size;
    private String color;
    private String wood;

    public TireV2(int size, String color, String wood) {
        this.size = size;
        this.color = color;
        this.wood = wood;
    }
    public void init() {
        System.out.println("Tire v2 size:" + size);
    }
}

这种方式的代码, 就算客户需求再怎么多变,  我的代码也只是需要更改整个依赖链上最底层依赖的代码和测试代码即可, 中间的代码都不需要改变.

对比两种开发模式:

>> 传统开发: 开发一辆车的时候, 我们先是创建 Car 对象, 然后再创建 Framework , Bottom ....对象,  是从上往下创建的,并且控制关系是上级对象直接控制着下级对象。

>> 控制反转开发: 先创建下级对象, 然后才会创建上级对象, 并且是把下级对象作为参数注入到上级对象去使用的, 此时下级对象的控制权就不在上级对象手里了, 这就是典型的控制反转思想 (IoC 思想)

4. 理解Spring 核心 - IoC

经过前面的讲解, 我们已经知道 Spring 是一个包含了众多工具方法的控制反转的 IoC 容器 , 那么既然是一个容器的话, 它最基本的功能又是什么呢? 我们学的数据结构中的集合就是用于存取数据的, 此处的 Spring 最核心的两个功能也就是存储对象到 Spring 中 和 从Spring 中获取对象.

【对比】为什么要使用 Spring 存储对象和获取对象,这相比于普通的 new 的方式有什么优势呢 ?

通过的 new 的方式创建和使用对象时, 当每次需要时, 就去 new , 用完了就不要了也不会保存, 下次还要使用的时候还得 new , 同样的事情要做很多遍。

而 Spring 是一个 IoC 容器, 把对象存储进去之后, 我想用的时候, 就从里面拿, 不想用的时候又放回去, 并且对象的创建和销毁的都交给 Spring 来管理了, 这样就很方便.

【谈谈 DI】

谈到 IoC, 就免不了谈到 "DI", 什么是 DI, DI 全称 Dependency Injection. 中文意思就是 "依赖注入".

什么是依赖注入?

依赖注入就是当程序在 IoC 容器中运行期间, 动态的将所需要的对象或者是某种依赖关系动态的注入到对象中. 简单来说和从 Spring 中获取出来对象差不多, 本身 "依赖注入" 和 "控制反转" 就是在描述同一件事情(引入 IoC 容器, 利用依赖关系, 实现对象之间解耦), 只不过角度不同而已. 

IoC 是一种 "思想"(/目标), 而 DI 更是一种具体的实现!!

下篇博客就开始进入 Spring 正题咯~

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

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

相关文章

[UE笔记]客户端服务器时间同步

内容系看教程所做的笔记 时间 往返时间(RTT, Round-Trip Time):数据从客户端通过网络发送到服务器,再从服务器返回到客户端所需的时间。 首先客户端应当知道服务端的当前时间。 服务器启动时间总是先于客户端的,客户…

【学习OpenCV4】OpenCV入门精讲(C++/Python双语教学)

大家好,我在CSDN开的OpenCV课程已经开课了,入口如下: OpenCV入门精讲(C/Python双语教学) 课程开始快一周了,收到了广大同学们的欢迎。 (1)评分很高; (2&#…

从Clickhouse 到 Snowflake: 云原生

云原生Clickhouse优势概述 以Clickhouse为基础,借鉴Snowflake等系统的设计思路,打造一款高性能的云原生OLAP系统,为用户提供多场景下的一站式的数据分析平台。 简单、易维护:集群管理、统一共享分布式调度服务高可用、可扩展&am…

T292114 [传智杯 #5 练习赛] 清洁工

题目描述 有一个 n\times nnn 的地块,一个连续 ii 分钟没人经过的地面在第 ii 分钟会落上 ii 个单位的灰,有人经过时不会落灰但灰也不会清零,在人走后第一分钟又会落上一个单位的灰,以此类推。你在这个 n\times nnn 的范围内移动…

深度可分离卷积神经网络与卷积神经网络

在学习语义分割过程中,接触到了深度可分离卷积神经网络,其是对卷积神经网络在运算速度上的改进,具体差别如下: 一些轻量级的网络,如mobilenet中,会有深度可分离卷积depthwise separable convolution&#…

Xamarin.Andorid实现界面弹框

目录1、使用系统自带的样式1.1 具体实现1.2 效果2、自定义样式的实现2.1 预期效果2.2 具体实现2.3 相关知识3 代码下载4、参考在App的实际使用中,一定会出现弹框选择的情况。如图所示: 因此非常有必须学会及使用弹框的功能,因此本次学习Xama…

miui刷机完整教程

风险提示:刷机有可能损害手机,本作者不承担因为使用本方法刷机引起的任何问题,请谨慎刷机。 1.选择[刷机包](https://web.vip.miui.com/page/info/mio/mio/detail?postId37093637&app_versiondev.20051) 2.解BL锁 浏览器打开http://www…

SSM整合(二)

SSM框架整合之mybatis查询的两个例子 1 准备工作 1.1 创建查询工作所需要的实体类Emp package com.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import tk.mybatis.mapper.annotation.KeySql; import javax.persisten…

代码随想录算法训练营第四天|24、19、面试题 02.07、142、92(寄了)

Leecode24. 两两交换链表中的节点 链接:https://leetcode.cn/problems/swap-nodes-in-pairs/ 其实这道题的思路和203比较相似,因为若是不设置虚拟头结点的话,处理头结点的方式和处理非头结点的方式会不一样,所以还是设置虚拟头结…

LeetCode力扣刷题——指针三剑客之三:图

图 一、数据结构介绍 作为指针三剑客之三,图是树的升级版。图通常分为有向(directed)或无向(undirected),有 循环(cyclic)或无循环(acyclic),所有…

Golang入门笔记(15)—— 数组和切片

编程的世界中,或许是因为一次一次的定义变量,维护管理起来都太费劲了,所以推出了数组,将数据用数组的形式管理起来。 Go的数组和Java的实现机制是不同的,Go语言的数组是作为基本数据类型存在的。所以数组是开辟在栈帧中…

Golang Web开发一键生成各层级模板代码

文章目录go_project_quickstart快速开始要求安装项目实现架构设计代码逻辑统一的调用逻辑代码复用每次写web项目,模板都是统一的,每次都要写大量冗余的代码会很烦,在Java中有很多逆向生成的工具,而Go语言我找了很久,也…

手把手搭建springboot项目,并测试springDataJPA

这篇文章记录了搭建springboot项目并测试springDataJPA的过程,接下来一起看看吧。 1.访问阿里云java脚手架网站 点击访问 2.按照下图勾选并获取代码 3.将获取到的代码解压到idea工作空间。 下图的JPAdemo就是我的项目 4.打开idea,导入项目 5.在pom…

【Redis】| 01 | Redis 可视化工具RedisInsight

目录1 RedisInsight 简介2 RedisInsight 安装2.1 安装2.1.1 软件安装2.1.1.1 下载 RedisInsight 软件包2.1.1.2 安装命令2.1.1.3 配置环境变量2.1.1.4 启动服务2.1.2 Kubernetes 安装2.1.2.1 创建 RedisInsight 的 yaml 文件2.1.2.2 启动3.RedisInsight 使用3.1 安装redis3.1.1…

Jacobi迭代的MPI进阶——计算通信重叠和虚拟进程的使用

1:条形分割的几种策略 这里先放Makefile和run.slurm Makefile CC = mpicc FLAGS = -O3 -Wall OBJ = *.o EXE = hang hangstartall Ihang xunihang qipan srqipan Isrqipan qipanendall: ${EXE}hang: hang.c $(CC) -o $@ $^ $(FLAGS)

信息安全结业复习题(选择 + 填空 + 简答 + 计算 + 设计 )含历年考题

这里写目录标题客观题知识点简答题计算题设计题客观题知识点 考过填空 密码学是保障信息安全的核心、信息安全是密码学研究和发展的目标 保证数字信息机密性的最有效方法是使用密码算法对其进行加密(对称和非对称) 保证信息完整性的有效方法是利用hash…

SQL Server全套教程(基于SQL语句----续更中)

SQL Server全套教程全程干货1. 数据库的基础操作1.1.0 创建数据库1.1.1 查看及修改数据库1.1.3 分离、附加和删除数据库2.数据库表的相关操作2.1.0 常用数据类型2.1.1 表结构的创建2.1.2 表结构的查看及修改1. 数据库的基础操作 1.1.0 创建数据库 数据库创建语法 -- 创建数据…

MicroPython-On-ESP8266——8x8LED点阵模块(2)使用74HC595驱动

MicroPython-On-ESP8266——8x8LED点阵模块(2)使用74HC595驱动 1. 使用74HC595驱动的原理 1.1. 基础回顾 上篇我们学习了8x8LED点阵屏的电路基础知识和驱动的原理,见 8x8LED点阵模块(1)驱动原理 里面也提到了&…

基于ssm+Javaweb的OA小型企业资源管理系统-计算机毕业设计

小型OA企业资源管理系统基于SSM(SpringSpringMVCMyBatis)框架,适用于毕业设计,采用javaweb,基于B/S模式,Myeclipse或者eclipse idea为开发工具,mysql数据库,主要包括登录模块、人事管理模块、公告管理模块、产品管理模块、和退出模块等多个模块。 本系统主要包含了…

MySQL高级篇知识点——主从复制

目录1.主从复制概述1.1.如何提升数据库并发能力1.2.主从复制的作用2.主从复制的原理2.1.原理剖析2.2.复制的基本原则3.一主一从架构搭建3.1.准备工作3.2.主机配置文件3.3.从机配置文件3.4.主机:建立账户并授权3.5.从机:配置需要复制的主机3.6.测试3.7.停…