Spring 初始导读

news2024/11/24 9:40:23

1.Spring初始

1. 为什么要学框架

学习框架相当于从"小作坊"到"工厂"的升级 , 小作坊什么都要做 , 工厂是组件式装配 , 特点就是高效.

2.框架的优点展示(SpringBoot Vs Servlet)

使用SpringBoot 项目演示框架相比 Servlet 所具备的以下优点:

  1. 无需配置 Tomcat , 点击"运行" 按钮就可以运行项目 , SpringBoot 内置了Web 容器(可直接运行)
  2. 快速添加 jar 包
  3. 快速发布项目(使用 java-jar 方式就可以发布)
  4. 对象自动装配

2.Spring基础与核心概念

1.Spring 是什么?

Spring 指的是 Spring Framwork (Spring 框架) , 用一句话来说 , Spring 是包含了众多工具方法的 IoC 的容器.

1.1 什么是容器

容器是用来容纳某种物品的装置.

  • List/Map -> 数据存储容器
  • Tomcat -> Web 容器(存储很多 Servlet 程序)

1.2 什么是 IoC

IoC = Inversion of Control (控制反转) , 也就是说 Spring 是一个 “控制反转” 的容器 , 听上去很抽象 , 下面这个示例可以很好的解释.

传统程序开发:

假如我们开发一个车的程序 , 大致实施思路是这样的.

构建一个车(Car)需要依赖车架(Framworl) , 车架需要依赖底盘(Bottom) , 底盘需要依赖轮胎(Tire) , 代码大致如下:

public class Car {
    public void init(){
        Framework framework = new Framework();
        System.out.println("do car");
        framework.init();
    }
    public static void main(String[] args) {
        Car car = new Car();
        car.init();
    }
}
public class Framework {
    public void init(){
        Bottom bottom = new Bottom();
        System.out.println("do framework");
        bottom.init();
    }
}

public class Bottom {
    public void init(){
        Tire tire = new Tire();
        System.out.println("do bottom");
        tire.init();
    }
}

public class Tire {
    private int size = 17;
    public void init(){
        System.out.println("size ->>" + size);
    }
}

如果我们系统升级 , 客户可以任选车轮尺寸 , 这时就会发现很大的缺陷 , 当最底层发生改变时 , 整个调用链都需要修改 , 说明代码的耦合性太强.

public class Tire {
    private int size = 17;
    public Tire(int size){
        this.size = size;
    }
    public void init(){
        System.out.println("size ->>" + size);
    }
}
public class Bottom {
    private Tire tire;
    public Bottom(int size){
        tire = new Tire(size);
    }
    public void init(){
        System.out.println("do bottom");
        tire.init();
    }
}
public class Framework {
    private Bottom bottom;
    public Framework(int size){
        bottom = new Bottom(size);
    }
    public void init(){
        System.out.println("do framework");
        bottom.init();
    }
}
public class Car {
    private Framework framework;
    public Car(int size){
        framework = new Framework(size);
    }
    public void init(){
        System.out.println("do car");
        framework.init();
    }
    public static void main(String[] args) {
        Car car = new Car(25);
        car.init();
    }
}

那么随着系统的迭代升级 , 人们有了更多的需求 , 底层千变万化 , 我们就会发现需要耗费大量的时间去修改整个调用链 , 因此需要解耦.

解决传统开发中的缺陷

传统开发的最主要缺陷就是 , 一个模块在依赖另一个模块的同时还控制其生命周期(new 下级) , 因此当下游模块发生改动 , 上游也要跟着改 , 那么我们解决这个问题的办法就是将原来自己创建下级类 , 改为传递的方式(也就是注入的方式) , 这样当下级类发生变化 , 当前类也无需修改任何代码 , 这样就解决了程序的解耦.

解耦指的是解决了代码的耦合性 , 耦合性也可以换一种叫法叫程序相关性 , 好的代码程序的耦合性(代码之间的相关性)是很低的.

这就好比打造汽车时 , 如果所有配件都是自己造的 , 那么当客户需求发生改变的时候 , 例如修改尺寸 , 那就需要我们自己动手来改了 , 如果我们将轮胎外部出去 ,那么即使轮胎的尺寸发生变化 , 我们只需向代理工厂下订单即可.

控制反转式程序开发

基于以上思路 , 我们把调用汽车的程序示例改造一下 , 把创建子类的方式 , 改为调用子类 , 具体实现代码如下:

public class Test {
    //交给 Test 这个第三方类来控制
    public static void main(String[] args) {
        Tire tire = new Tire(20, "白色");
        Bottom bottom = new Bottom(tire);
        Framework framework = new Framework(bottom);
        Car car = new Car(framework);
        car.init();
    }
}
public class Tire {
    private int size; //客户不再满足与17尺寸
    private String color;//客户新增颜色需求
//    新增 尺寸 和 颜色需求

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

    public void init() {
        System.out.println("size ->>" + size + " color ->>" + color);
    }
}
public class Bottom {
    private Tire tire;

    public Bottom (Tire tire){
        this.tire = tire;
    }
    public void init(){
        System.out.println("do Bottom");
        tire.init();
    }
}
public class Framework {
    private Bottom bottom;

    public Framework(Bottom bottom){
        this.bottom = bottom;
    }

    public void init(){
        System.out.println("do Framework");
        bottom.init();
    }
}
public class Car {
    private Framework framework;

    public Car(Framework framework){//不再控制 Framework 的生命周期, 只使用并不关心谁创建(解耦).
        this.framework = framework;
    }
    public void init(){
        System.out.println("do cat...");
        framework.init();
    }
}

1.3 理解 Spring IoC

Spring IoC 核心操作:
  1. 将对象存入到容器中
  2. 从容器中取出对象

也就是说学 Spring 最核心的功能 , 就是学如何将对象存入到 Spring 中 , 再从 Spring 中获取对象的过程.

将对象放入容器的好处: 将对象存储到 IoC 容器相当于将以后可能用到的工具都放好到仓库中 , 需要的时候直接取即可 , 用完再放回到仓库中. 而 new 对象的方式相当于 , 每次需要工具的时候都要自己动手去做 (new对象) , 用完之后直接丢弃不保存(销毁对象) , 下次再用的时候还得重写去做 , 这就是 IoC 和普通程序开发的区别.

Spring 是一个 IoC 容器 , 说得是对象的创建和销毁的权利都交给 Spring 来管理了 , 它本身又具备了存储对象和获取对象的能力.

Spring IoC 的优点:
  1. 解耦
  2. 使用更加方便(无需手动创建和关注这个类对象背后的依赖关系 )
  3. 更加高效(类似于使用线程和线程池的区别)

如果 A 要依赖 B , 而 B 又依赖 C D E , 如果我们使用传统的开发方式 , 不但需要自己手动实现 B C D E , 而且下游的子类发生改变 , 上游的父类也要跟着改变. 但如果我们使用 Spring IoC , 无需自己手动实现依赖 , 也无需关注后续的依赖方法.


1.4 DI 概念说明

说到 IoC 就不得不提另一个词 “DI” , DI 是 Dependency Injection 的缩写 , 也就是"依赖注入".

所谓依赖注入 , 就是在 IoC 容器运行期间 , 将依赖的某个对象动态的注入到当前类的行为(主动). 所以依赖注入(DI) 和控制反转(IoC) 是从不同的角度描述了同一件事 , 就是指通过引入 IoC 容器 , 利用依赖注入的方式 , 实现对象之间的解耦.

IoC 是一种思想 , 而 DI 是一种具体的实现技术 , 也就是通过 DI (依赖注入) 来实现 IoC 思想.

例如: 学生每天会问老师很多的问题 , 老师被动的去接收问题就是传统的开发模式 , 如果老师掌握主动权 , 每天去督促学生 , 这就相当于 依赖注入.

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

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

相关文章

Three.js 实战【1】—— 3D全景视图开发

Three.js 实战【1】—— 3D全景视图开发 摘要 1、3D视图Demo2、准备工作——搭建好一个开发环境3、RGBELoader——高范围动态图像加载器4、HDR——高动态范围图像5、使用HDR实现3D全景视图6、直接通过图片纹理进行实现 摘要 在现代开发过程当中,3D开发是越来越不可…

find,which,whereis,grep,bc,uname,free,nano,history指令的语法,功能与选项等

Tips x86_64 与 x64 都是指 64位x86 指的是 32位 find指令的语法,功能与选项 语法:find 目录 -name 文件名功能:在指定的目录之下进行文件查找(递归式查找)选项:它的选项也非常多,讲个 -name…

【Java 基础】File IO流

文章目录 1. File1.1 File类概述和构造方法1.2 绝对路径和相对路径1.3 File 类的常用方法1.4 递归删除文件夹及其下面的文件 2. IO2.1 分类2.2 字节输出流2.3 字节输入流2.4 文件的拷贝2.5 文件拷贝效率优化2.6 释放资源2.7 缓冲流2.8 编码表 3. commons-io 工具包3.1 API 1. F…

VSCode中安装GPT插件详细教程+gpt4改进

目录 安装插件 A.安装CodeGPT B.安装chatgpt 1.VSCode安装插件,使用本地下载vsix文件 2.获取 ChatGPT API 密钥 3.配置settings.json gpt4和3.5对比 GPT-4主要有三大改进点 局限性 安装插件 AB功能一样,A安装的人最多,GPT具体功能可…

K8s之标签、Node选择器与亲和性详解

文章目录 一、标签1、标签是什么?2、给Pod打标签3、给Node节点打标签4、查看标签资源 二、Node选择器1、nodeName(指定Pod调度到指定Node节点)2、nodeSelector(指定Pod调度到具有指定标签的Node节点) 三、亲和性1、Node亲和性-nodeAffinity2、Pod亲和性-podAffinity…

软件测试项目实战经验附视频以及源码【医疗项目,社区管理,前后端分离项目,银行项目,金融项目,车载项目】

前言: ​​大家好,我是测试小马。 很多初学的测试小白都在烦恼找不到合适的项目去练习,这也是难倒大部分测试小白的一个很常见的问题,项目经验确实是每一个测试非常宝贵的经验!这里小马哥给大家找了一些常用的项目合…

AJ-Captcha验证码使用教程源码解读

1.背景 验证码的主要作用是防止机器人恶意使用我们的程序........ 今天我们结束一款强大的验证码组件:aj-captcha 官方文档:AJ-Captcha在线体验 大家一定要认真阅读官方文档 2.项目启动与快速测试 启动后端: 快速页面测试: 使用浏览器访问这个页面 有修改后端源码的情况…

MySQL触发器Trigger加载以及目前局限

GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。作者: 亮文章来源:GreatSQL社区原创 概念介绍 首先需要知道MySQL中触发器特点,以及表table…

掌握这些技巧,让你的Facebook文案更具说服力!

面对广告瀑布流般的竞争,如何让自己的Facebook广告脱颖而出,吸引到用户的眼球,成为广告运营人员必须思考的问题。在这个过程中,文案的作用是至关重要的。 优秀的文案不仅可以吸引用户点击,还能让用户产生共鸣&#xf…

K8s scheduler 调度:预选和优选策略

1 环境准备 kube-scheduler是k8s的核心组件之一,主要负责Pod的调度。scheduler通过监听kube-apiserver,查询未分配 Node的Pod,根据配置的调度策略,将Pod调度到最优的工作节点上,从而高效、合理地利用k8s集群资源。 在m…

shell之数组

一. 关于数组的命令 1. 定义数组 数组名(value0 value1 value2 …) arr(元素1 元素2 元素3 ...) echo ${arr[]}数组名([0]value [1]value [2]value…" arr ([下标1]值1 [下标2]值2 ....) echo ${array3[]}列表名"value0 value1 value2 list"值1 值2 值3 ..…

一文解读spring中事务管理

目录 声明式事务概念 事务基本概念 ①什么是事务 ②事务的特性 编程式事务 声明式事务 基于注解的声明式事务 准备工作 测试无事务情况 加入事务 Transactional的使用 事务属性:只读 事务属性:超时 事务属性:回滚策略 事务属性…

华为OD机试真题 Java 实现【寻找链表的中间结点】【2023Q1 100分】

一、题目描述 给定一个单链表 L,请编写程序输出 L中间结点保存的数据。如果有两个中间结点,则输出第二个中间结点保存的数据。 例如: 给定 L 为 1 -> 7 -> 5,则输出应该为 7; 给定 L 为 1 -> 2 -> 3 -> 4&#…

微服务简介,SpringCloud Alibaba Nacos的安装部署与使用,Nacos集成springboot实现服务注册

目录 一.认识微服务 1.0.学习目标 1.1.单体架构 单体架构的优缺点如下: 1.2.分布式架构 分布式架构的优缺点: 1.3.微服务 微服务的架构特征: 1.4.SpringCloud 1.5Nacos注册中心 1.6.总结 二、Nacos基本使用安装部署服务注册 &am…

聊一聊适配器模式

接口不能用?行,我帮你适配 一、概述 适配器模式(Adapter),是23种设计模式中的结构型模式之一;它就像我们电脑上接口不够时,需要用到的拓展坞,起到转接的作用。它可以将新的功能和原…

SCS【26】单细胞细胞间通信第二部分通信网络的系统分析(CellChat)

桓峰基因公众号推出单细胞生信分析教程并配有视频在线教程,目前整理出来的相关教程目录如下: Topic 6. 克隆进化之 Canopy Topic 7. 克隆进化之 Cardelino Topic 8. 克隆进化之 RobustClone SCS【1】今天开启单细胞之旅,述说单细胞测序的前世…

《微服务实战》 第十一章 Spring Cloud Alibaba nacos配置中心

前言 Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。 Spring Cloud Aliba…

【C++ 入坑指南】(08)循环

文章目录 一、while 循环二、do...while 循环三、for 循环四、嵌套循环五、跳转语句5.1 break 语句5.2 continue 语句5.3 goto 语句 有的时候,可能需要多次执行同一块代码。一般情况下,语句是顺序执行的:函数中的第一个语句先执行&#xff0c…

c++ 11标准模板(STL) std::set(五)

定义于头文件 <set> template< class Key, class Compare std::less<Key>, class Allocator std::allocator<Key> > class set;(1)namespace pmr { template <class Key, class Compare std::less<Key>> using se…

Java中的线程通信的几种方式

Java中的线程间通信是指不同线程之间相互协作&#xff0c;以完成一些复杂的任务或实现某些功能的过程。线程间通信主要包括两个方面&#xff1a;线程之间的互斥和同步&#xff0c;以及线程之间的数据共享和通信。Java提供了多种方式来实现线程间通信&#xff0c;本文将介绍Java…