Spring 是什么

首先我们先看一个例子。以下是代码的结构。

public interface UserDAO {/*** 根据id删除用户*/void deleteById();
}
public class UserDAOImplForMySQL implements UserDAO {@Overridepublic void deleteById() {System.out.println("使用MySQL数据库删除信息....");}
}
public interface UserService{/*** 删除用户信息*/void deleteUser();
}
public class UserServiceImpl implements UserService {private UserDAO userDAO = new UserDAOImplForMySQL();@Overridepublic void deleteUser() {userDAO.deleteById();}
}
public class UserAction {private UserService userService = new UserServiceImpl();/*** 删除用户信息的请求*/public void deleteRequest() {userService.deleteUser();}}
public class UserTest {@Testpublic void test() {UserAction userAction = new UserAction();userAction.deleteRequest();}
}

以上代码代码现在看起来没有什么问题对吧。

好的。现在我有一个新的需求:我想要使用付费的 Oracle。

此时怎么做呢?当然就是新建一个 Oracle 的实现类了

public class UserDAOImplForOracle implements UserDAO {@Overridepublic void deleteById() {System.out.println("使用Oracle数据库删除信息....");}
}

此时,直接执行还是使用的 MySQL。我们需要去改变之前写好的代码,才可以实现这个需求。

public class UserServiceImpl implements UserService {private UserDAO userDAO = new UserDAOImplForOracle();@Overridepublic void deleteUser() {userDAO.deleteById();}
}

这违背了软件开发原则中的 开闭原则依赖倒置原则

以下先分别介绍这两种原则。

开闭原则(OCP)

  • OCP 开闭原则是软件七大开发原则当中最基本的一个原则。
  • OCP 开闭原则:
    • 在软件开发过程中应当对扩展开放,对修改关闭。
    • 在软件开发过程中,通过添加额外的类对原先程序已有的功能进行扩展是没问题的,但是如果因为要进行功能扩展而修改之前运行正常的程序,这是不被允许的。
    • 因为一旦修改之前运行正常的程序,那么项目整体就要进行重新测试,这会导致额外的开销和资源消耗,并且测试过程相当麻烦。
  • OCP 开闭原则是最核心的、最基本的,其他的六个开发原则都是为这个原则服务的。
  • 是否违反 OCP 开闭原则的判断:
    • 只要你在扩展系统功能的时候,没有修改以前写好的代码,那么你就是符合 OCP 原则的。
    • 反之,如果在扩展系统功能的时候,你修改了之前的代码,那么这个设计是失败的,违背了OCP原则。

依赖倒置原则(DIP)

  • 依赖倒置原则,就是不再显示的建立类之间的关联关系,而是面向接口编程,面向抽象编程,不要面向具体编程,从而降低程序的耦合度,提高程序的扩展力,增强代码复用性。
  • 依赖倒置原则的目的:降低程序的耦合度,提高程序的扩展力,增强代码复用性。
  • 是否符合依赖倒置原则:
    • 上 不依赖 下,就是符合,即类的实例对象之间没有明确固定在代码中的依赖关系。
    • 上 依赖 下,就是违背。只要“下”一改动,“上”就受到牵连。
  • 符合依赖倒置原则的编程思想:控制反转

控制反转(IoC)

  • 当前程序的设计,显然既违背OCP,又违背DIP,可以采用“控制反转”这种编程思想来解决这个问题。
  • 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计思想,可以用来降低代码之间的耦合度,符合依赖倒置原则。
    • 由于控制反转思想出现的比较新,所以没有被纳入GoF23种设计模式范围内。
  • 控制反转的核心思想:
    • 将对象的创建权交出去。
    • 将对象和对象之间关系的管理权交出去。
    • 对象的创建和对象之间关系的维护都由第三方容器来负责。
  • 控制反转中的反转是两件事:
    • 第一件事:不在程序中采用硬编码的方式来new对象了,将new对象的权利交出去。
    • 第二件事:不在程序中采用硬编码的方式来维护对象的关系了,对象之间关系的维护权交出去了。
  • 控制反转思想的实现:依赖注入

依赖注入(DI)

  • 控制反转的实现方式有多种,其中比较重要的叫做:依赖注入(Dependency Injection,简称DI)。
  • 依赖注入,用于实现对象之间关系的建立
  • 控制反转是思想。依赖注入是这种思想的具体实现。
  • 依赖注入DI,又包括常见的两种方式:
    • 第一种:set注入(执行set方法给属性赋值)
    • 第二种:构造方法注入(执行构造方法给属性赋值)
  • 依赖注入 中 “依赖”是什么意思? “注入”是什么意思?
    • 依赖:A对象和B对象的关系。
    • 注入:是一种手段,通过这种手段,可以让A对象和B对象产生关系。
  • 依赖注入:对象A和对象B之间的关系,靠注入的手段来维护。而注入包括:set注入和构造注入。

术语小结

  • OCP:开闭原则(开发原则)
  • DIP:依赖倒置原则(开发原则)
  • IoC:控制反转(一种思想,一种新型的设计模式)
  • DI:依赖注入(控制反转思想的具体实现方式)

什么是Spring

Spring 框架实现了控制反转IoC这种思想。

  • Spring框架可以帮你new对象。
  • Spring框架可以帮你维护对象和对象之间的关系。

Spring是一个实现了IoC思想的容器。

当然,Spring 不止实现了IoC,还有以下的特性。

  • Spring是一个开源框架。
  • Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
    • Spring实现了控制反转思想,Spring框架可以帮你维护对象和对象之间的关系
    • Spring实现了面向切面编程
    • 由于我们可以将创建对象交给Spring负责,所以Spring也是一个存放对象的容器
  • Spring为简化开发而生,让程序员只需关注核心业务的实现,尽可能的不再关注非业务逻辑代码(事务控制,安全日志等),这得益于AOP。

Spring 8大模块

  • Spring5版本之后是8个模块。在Spring5中新增了WebFlux模块。

Spring 的特点

  1. 轻量
    1. 完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布,并且Spring所需的处理开销也是微不足道的。
    2. Spring是非侵入式的:spring框架的运行不需要依赖其他框架
  1. 控制反转
    1. Spring实现了控制反转思想
  1. 面向切面
    1. Spring提供了面向切面编程的丰富支持
    2. 允许开发者只需专注于业务逻辑的开发,与核心业务无关的代码可以以切面的方式加入核心业务代码的执行过程中,将核心业务的执行流程看成是纵向执行的,与核心业务无关的代码(如事务、日志等)可以以横向切面的方式加入核心业务的执行过程中
  1. 容器
    1. Spring 可以包含并管理应用对象的配置和生命周期,即Spring可以负责对象的创建到对象的销毁这整个生命周期过程中对象的维护和管理,Spring就好比一个存放和管理对象的容器
  1. 框架
    1. Spring可以将简单的组件配置、组合成为复杂的应用。

 Spring 对 JDK 的要求

  • Spring6要求JDK最低版本是Java17

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DexclassLoader读取dex在Android14上遇到问题

报错如下: 在Android 14(API 级别 34)及以后版本中,DexClassLoader 被进一步限制,只能用于加载只读文件中的代码。这意味着你不能再使用 DexClassLoader 来加载从应用的内部存储空间中读取的文件。 我想通过JNI来修改…

新160个crackme - 043-riijj_cm_20041121

运行分析 除了主程序还有一个dll文件,应该是要加载pf1.dll这个动态链接库运行主程序,需破解Name和Serial,点击注册无反应 PE分析 C程序,32位,无壳 静态分析&动态调试 尝试ida动调加载动态链接库pf1.dll&#xff0c…

【SAM】Segment Anything网络结构详解

Segment Anything网络结构详解 论文链接:http://arxiv.org/abs/2304.02643 代码链接:https://github.com/facebookresearch/segment-anything 一、整体框架 二、图像编码器image encoder 使用一个MAE预训练好的ViT模型(ViT-H/16 使用了 14…

如何在JPG文件中隐写数据

概述 最近在做资源管理器背景的一个功能时,需要将信息传递到DLL中去, 主要就是传递一些比较简单的参数,包括图片的契合度,透明度之类的。通信方式有多种,毕竟是练手的功能,就想找一些以前没用过的方式。 …

基于STM32校车安全监控系统的设计(论文+源码+实物)

1 方案设计 根据设计要求,本设计校车安全监控系统的设计以STM32F103单片机作为主控制器,通过MQ传感器实现异常气体的检测,当异常气体浓度异常时会通过继电器打开车窗进行通风,以保证舒适的环境,通过红外传感器用于监…

BUUCTF PWN wp--jarvisoj_level0

第一步 checksec ,该题为64位。 分析一下二进制保护机制: Arch: amd64-64-little 这个字段表示二进制程序的架构是 64 位的小端序的 x86-64 架构。小端序意味着低位字节存储在内存中的低地址上,高位字节存储在高地址上。RELRO: No RELRO …

【Java】 为什么是split 方法按点号分割是用 “ \\. “ ?

前言: 小知识,记录自用and分享。 原因分析: 字符串的很多方法是可以使用正则表达式的,这里就包括了split这个方法。 . 在正则表达式里的意思是通配符,表示:匹配任意单个字符。那么,当使用split…

vue.js项目实战案例详细源码讲解

​ 大家好,我是程序员小羊! 前言: 为帮助大家更好地掌握Vue.js项目的开发流程,我将为你讲解一个完整的Vue.js实战案例,并提供详细的源码解析。这个案例将涵盖从项目创建到实现各种功能模块的全过程,适合用于…

媲美Flux pro! Ideogram 发布了 2.0 图像生成模型, 照片级真实感和高质量文本渲染!

Ideogram 发布了 2.0 模型,图像生成质量大幅提高,产品易用性改善,文字生成能力也提升许多。Ideogram 2.0 在图像快速对齐、照片级真实感和文本渲染质量方面取得了显著进步。人工评估一致认为 Ideogram 2.0 比 Flux Pro 和 DALLE 3 有了显著改进。尽管我们…

python网络爬虫(四)——实战练习

0.为什么要学习网络爬虫 深度学习一般过程:   收集数据,尤其是有标签、高质量的数据是一件昂贵的工作。   爬虫的过程,就是模仿浏览器的行为,往目标站点发送请求,接收服务器的响应数据,提取需要的信息&#xff0c…

vscode 未定义标识符 “uint16_t“C/C++(20) 但是可以顺利编译

这是没有指定编译器的原因 解决方法: 打开 或c_cpp_properties.json,添加编译器

AIGC提示词(2):塑造未来内容创作的核心力量

引言 🌟 在这个数字化的时代,人工智能生成内容(AIGC)正变得越来越普遍。从自动写作到图像生成,AI正以前所未有的速度和多样性创造内容。然而,要实现高质量和相关性强的内容生成,关键在于有效地…

PyCharm 自定义字体大小

常用编程软件自定义字体大全首页 文章目录 前言具体操作1. 打开设置对话框2. 设置编辑器字体3. 选择外观字体 前言 PyCharm 自定义字体大小,统一设置为 JetBrains Mono 具体操作 【File】>【Settings...】>【Editor】>【Font】 统一设置为字体样式 JetB…

算法基础-离散化

1、a数组可能存在重复元素 去重 排序 2、如何算出 x 离散化后的值 二分 1、add 和 query 记录每次填入的两个数 2、将位置 x 和每次询问的两个数 l 和 r 添加到 alls 进行排序去重 3、通过Collections.binarySearch映射(一定能找到,不用判…

如何构造哈夫曼树

目录 一、哈夫曼树的概念 1、结点的权: 2、结点的带权路径长度 3、树的带权路径长度 4、哈夫曼树 二、哈夫曼树的构造 1、构造步骤 三、哈夫曼树的编码 一、哈夫曼树的概念 1、结点的权: 定义: 每个结点的权重(重要性…

Linux终端简单配置(Vim、oh-my-zsh和Terminator)

文章目录 0. 概述1. 完整Vim配置2. Vim配置方案解释2.1 状态行与配色方案2.2 文件管理与缓存设置2.3 搜索与导航优化2.4 缩进与格式化设置2.5 粘贴模式快捷切换2.6 文件编码与格式2.7 性能优化 3. 安装 Oh My Zsh 及配置3.1 安装 Oh My Zsh3.2 Oh My Zsh 配置 3. Terminator终端…

Linux Grep案例

目录 一. 查询两个文件第一列的数据并去重二. 抽取日志中指定的字段三. 服务器指定时间点异常查询四. 从csv文件中抽取指定的数据五. 获取除了空白行和注释之外的部分 一. 查询两个文件第一列的数据并去重 📚file1.log 123 aaa 你好 345 bbb 我好 345 ccc 大家好 …

神经网络搭建实战与Sequential的使用

一、需要处理的图像 二、对上述图片用代码表示: import torch from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linearclass SUN(nn.Module):def __init__(self):super(SUN, self).__init__()self.conv1 Conv2d(3, 32, 5, padding2)self…

RSTP的改进有哪些

华为设备生成树有几种模式? 4种模式:传统STP(802.1D)、RSTP(802.1w)、MSTP(802.1s)、VBST(基于VLAN的生成树,兼容某些厂商的每VLAN一颗生成树) A…

【大数据算法】时间亚线性算法之:串相等判定算法。

串相等判定算法 1、引言2、串相等判定算法2.1 定义2.2 核心原理2.3 应用场景2.4 算法公式2.4.1 Rabin-Karp算法2.4.2 哈希函数 2.5 代码示例 3、总结 1、引言 小屌丝:鱼哥, 啥是串相等判定算法啊 小鱼:这个… en…en… 小屌丝:咋…