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

【Spring基础】从0开始学习Spring(2)

前言

在上篇文章,我已经讲了Spring中最核心的知识点:IoC(控制反转)以及DI(依赖注入)。这篇文章,我将讲一下关于Spring框架中的其它比较琐碎但是又还是挺重要的知识点,因此,如果没有阅读过我上篇文章,建议先看一下,这会对阅读接下来的内容有着很好的帮助:【IoC控制反转】看完必定强大!立刻奏效!-CSDN博客

1. 什么样的架构,我们认为是一个优秀的架构?

我认为是可维护性好,可扩展性好的架构。

那什么叫可扩展性好呢?

其实我的理解就是在不断添加新的代码的同时,可以不修改原有代码。

那如何让程序维护性好,可扩展性好呢?

在Java业界是有一个公认的标准的:高内聚,低耦合。

高内聚就是尽量将代码写在与之功能描述一致的模块中。如User表的操作写在UserDAO里面,不要写在非UserDAO的类里面。低耦合就是尽量减少类与类之间的直接关系。

什么是直接关系?

Controller层依赖Service层,在Controller层直接new Service层的类的对象。Service层依赖Dao层,在Service层直接new Dao层的对象。

Spring框架就是通过IoC/DI(控制反转/依赖注入)实现程序的解耦。从而提高程序的维护性和扩展性。

2. Spring是什么?这个框架到底有啥用?

定义:Spring是一个JavaEE轻量级的一站式开发框架。

JavaEE: 就是用于开发企业级(B/S)应用的技术。

轻量级:使用最少代码启动框架,然后根据需求选择需要使用的模块。

一站式:提供了表示层,服务层,持久层的所有支持。

我猜你不懂我在说什么,因为这是定义,比较晦涩,所以我讲一下我自己对于Spring定义的理解吧。

什么是轻量级?

就是除内核模块,其他模块由开发者自由选择使用,同时支持整合其他框架。也可以称为可插拔式开发框架,像插头和插座一样,插上就用,不用就拔下来。这就是Spring框架核心理念。

什么是一站式?

就是Spring框架提供涵盖了JavaEE开发的表示层,服务层,持久层的所有组件功能。也就是说,原则上,学完一套Spring框架,不用其他框架就可以完成网站一条流程的开发。

Spring的所有组件如下图:

总结一下,Spring是一个JavaEE轻量级一站式开发框架。它提供的功能涵盖了JavaEE程序中的表示层,服务层,持久层功能组件。这意味着,单单Spring框架就可以满足整个JavaEE程序的开发。但Spring框架,更加强调的是它的轻量级(模块的可插拔)。也就是说,除了内核模块,其他功能模块如果你想使用可以不用,并且Spring框架能够整合任何第三方的框架。在现实开发中,Spring主要用于整合其他框架

3. 为什么Spring可以实现模块的可插拔?

Spring之所以可以实现模块的可插拔是支持依赖注入,所谓的依赖注入就是不用new就可以创建对象。我来展示一下使用Spring框架,不用new创建一个对象。

我举一个NBA的例子,涉及球队(Team)和球员(Player)两个类,并使用Spring框架来管理它们之间的关系。

1.创建一个普通类,表示球队(Team),然后,我们创建另一个普通的Java类,表示球员(Player):

2. 创建一个Spring配置文件,命名为applicationContext.xml,用于描述类与类之间的关系。

3. 创建ApplicationContext容器对象,根据Spring配置文件的描述,创建对象并放在Spring容器里面。

4. 使用ApplicationContext容器对象的getBean方法,获取Spring容器里面的对象

4. XML管理Bean是啥东西?

XML管理对象(也称为XML管理Bean)是一种将对象的配置信息存储在XML文件中,并使用XML文件来创建和管理对象的方法。在这种模式下,XML文件用于定义对象的属性和配置,包括对象的类名、属性值、依赖关系等。XML文件可以被解析和读取,然后根据其中的配置信息创建相应的对象,并将对象的属性值设置为配置文件中指定的值。这种方式使得对象的创建和配置与代码的实现分离,提供了更大的灵活性和可配置性。

当涉及到XML管理对象(Bean)时,一个常见的例子是使用Spring Framework进行对象的配置和管理。我举一个例子,展示一下如何使用XML配置文件来定义和创建对象:

假设我们有一个名为"Person"的Java类,代表一个人的信息,包括姓名和年龄。我们将使用XML配置文件来管理"Person"对象。

首先,我们创建一个名为"beans.xml"的XML配置文件,内容如下:

在上述XML配置文件中,我们定义了一个名为"person"的Bean,它的类是"com.example.Person"。我们使用<property>元素来设置对象的属性值,这里设置了"name"属性为"John Doe","age"属性为"30"。

接下来,我们可以编写Java代码来读取和使用这个XML配置文件。假设我们有一个名为"MainApp"的类:

在上述代码中,我们使用Spring的ClassPathXmlApplicationContext类来加载XML配置文件,并创建一个应用程序上下文。通过调用getBean()方法,我们可以从上下文中获取配置的对象。在这个例子中,我们获取了名为"person"的Bean,并使用它的方法打印姓名和年龄。

运行这个示例代码,它将读取"beans.xml"配置文件,并创建一个"Person"对象,输出姓名和年龄。

看到这里,相信你已经理解了XML管理Bean是啥东西了。不过很遗憾的是,XML管理对象的方式逐渐被更现代的配置和管理方式所取代,如注解驱动的配置、Java配置类等。这些方式提供了更简单、更灵活和更强大的配置和管理功能,例如Spring Framework中的注解配置和Java Config。所以,这里我们只是了解一下大概是怎么回事儿就好,不需要说刻意去记忆。

5. bean是什么?如何实例化bean?

当谈到Spring中的Bean时,可以将其比喻为餐厅的菜单和菜品。

在一家餐厅中,菜单是表示可供选择的菜品的列表,而每道菜品则是一个具体的实例。类比到Spring中,菜单可以看作是应用程序的配置文件或注解,它列出了可用的Bean定义,而每个具体的菜品则对应于由Spring容器实例化和管理的Bean。

在餐厅里,菜单上的每道菜品都有自己的特点和属性,例如名称、描述、价格等。类似地,在Spring中,每个Bean也有自己的属性和配置信息,例如类名、依赖关系、作用域等。

当顾客在餐厅点菜时,服务员会根据菜单上的信息来准备并提供相应的菜品。类似地,在Spring中,当应用程序启动时,Spring容器会根据配置文件或注解中的信息来实例化和配置Bean,并在需要时将它们提供给其他组件使用。

通过菜单,顾客可以选择自己喜欢的菜品,并根据自己的需求定制。类似地,在Spring中,开发人员可以根据应用程序的需求选择和配置自己需要的Bean,以实现功能的定制和灵活性。

那如何实例化bean呢?就像这样:

反正你其实只要大概知道一下我们经常说的bean是什么?看到类似这种代码知道是在干啥就好了。

6. 能否举一个依赖注入的例子?

依赖注入有两种方法:构造函数注入和利用setter实现。下面我举一个构造函数注入的例子。为什么不举用setter实现的例子呢?因为我这篇文章只是让你简单了解一下依赖注入在代码中到底是怎么搞的,让你在脑海里有个印象,而且你不可能看了我一篇文章就直接可以徒手打出来吧哈哈。

例子如下:

假设我们有一个NBA球队管理系统,其中包含了以下几个关键组件:Team(球队)、Coach(教练)和Player(球员)。

在没有依赖注入的情况下,我们可能会在Team类中直接实例化Coach和Player,并在需要时直接调用它们的方法。就像这样:

在上述代码中,Team类直接依赖于Coach和Player,它在构造函数中创建了这两个对象的实例并使用它们。

然而,这种直接实例化的方式存在一些问题。首先,Team类与具体的Coach和Player类紧密耦合,难以进行单元测试和替换。其次,如果我们想在未来更改教练或球员的实例,需要修改Team类的代码。

通过使用依赖注入,我们就可以不修改Team的代码。我们可以将依赖的对象作为参数传递给Team类的构造函数或者通过setter方法注入。就像这样:

现在,Team类不再负责创建Coach和Player的实例,而是通过构造函数接收它们作为参数。这样,我们可以在应用程序的配置中注入具体的Coach和Player实例,实现了依赖的解耦。

例如,在Spring框架中,我们可以使用XML配置文件或注解来配置依赖注入。在配置文件中,我们可以指定具体的对象实例:

7. 怎么理解注入集合对象?

还是举一个例子:

假设我们有一个NBA球队管理系统,其中球队需要管理一组球员(Players)。我们希望通过依赖注入来将球员集合注入到球队对象中。

首先,我们定义一个Player类表示球员:

然后,我们定义一个Team类表示球队,它依赖于一个Player集合。我们可以使用构造函数注入或者属性注入来实现集合对象的注入。

(1)使用构造函数注入集合对象:

在上述代码中,Team类通过构造函数接收一个Player集合作为参数,并将其赋值给类的属性。通过遍历集合对象,我们可以依次调用每个球员的play()方法。

(2)使用属性注入集合对象:

在上述代码中,Team类提供了一个setter方法来接收Player集合对象,并将其赋值给类的属性。通过调用setter方法,我们可以将集合对象注入到Team类中。

无论是构造函数注入还是属性注入,我们都可以在使用依赖注入框架(如Spring)时配置集合对象的注入。例如,在Spring框架中,我们可以使用XML配置文件或注解来配置集合对象的注入。

XML配置文件的示例:

通过上述配置,Spring容器会自动创建Player对象并注入到Team类的players属性中。

后记

对于SpringAOP编程以及Spring JDBC这两个知识点,请看下篇文章!

【面向切面编程AOP】从0开始学习Spring---AOP的相关知识(2)-CSDN博客

相关文章:

【Spring基础】从0开始学习Spring(2)

前言 在上篇文章&#xff0c;我已经讲了Spring中最核心的知识点&#xff1a;IoC&#xff08;控制反转&#xff09;以及DI&#xff08;依赖注入&#xff09;。这篇文章&#xff0c;我将讲一下关于Spring框架中的其它比较琐碎但是又还是挺重要的知识点&#xff0c;因此&#xff…...

cesium mapboxgl+threebox glb 朝向问题

一、3Dbuilder打开glb 二、cesium在pitch和heading都为0的情况下&#xff0c;不设置模型的朝向 三、mapboxglthreebox在pitch和bearing都为0的情况下&#xff0c;不设置模型的朝向 四、对于地图默认视角&#xff0c;cesium设置pitch-90、heading0的时候和mapboxglthreebox设置p…...

LeetCode 打家劫舍

198. 打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个…...

单片机的50个电路

单片机 电源 声音模块 收音机 485 蓝牙 光耦 can 光敏电阻 单片机 矩阵 单片机电路 时钟 ADC 接口电路 红外发射 显示模块 红外接收 蜂鸣器驱动 流水灯 usb供电 烧录电路 数码管 EEPROM LCD1602电路 数码管 max485 红外开关 译码器 移位寄存器 步进电机控制 复位电路 下载电路 …...

JVM 性能调优- 五种内存溢出(5)

在介绍之前先简单介绍下 直接内存(Direct Memory)和堆内存(Heap Memory): 关系: 直接内存并不是Java虚拟机的一部分,它是通过Java的NIO库中的ByteBuffer来分配和管理的。直接内存通常由操作系统的本地内存(Native Memory)提供支持。堆内存是Java虚拟机的一部分,用于存…...

【SQL高频基础】1141.查询近30天活跃用户数

题目&#xff1a; 表&#xff1a;Activity ------------------------ | Column Name | Type | ------------------------ | user_id | int | | session_id | int | | activity_date | date | | activity_type | enum | ------------------------…...

基于spring cloud alibaba的微服务平台架构规划

平台基础能力规划&#xff08;继续完善更新…&#xff09; 一、统一网关服务&#xff08;独立服务&#xff09; 二、统一登录鉴权系统管理&#xff08;独立服务&#xff09; 1.统一登录 2.统一鉴权 3.身份管理 用户管理 角色管理 业务系统和菜单管理 部门管理 岗位管理 字典管…...

leetcode(滑动窗口)3.无重复字符的最长字串(C++详细题解)DAY2

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示…...

Android13 系统源码适配安装可卸载的三方apk应用

Android13 系统源码适配安装可卸载的三方apk应用 文章目录 Android13 系统源码适配安装可卸载的三方apk应用一、前言二、Android 系统运行后默认安装三方apk实现1、Android 系统默认安装三方apk实现主要思路2、Android 系统默认安装三方apk具体实现&#xff08;1&#xff09;准…...

flutter使用qr_code_scanner扫描二维码

qr_code_scanner仓库地址&#xff1a;qr_code_scanner | Flutter Package 需要添加android和ios的相机权限和本地相册权限&#xff1a; android中添加权限: 在android\app\build.gradle中修改&#xff1a;minSdkVersion 20 并且在android/app/src/main/AndroidManifest.xml中…...

黑马Java——集合进阶(List、Set、泛型、树)

一、集合的体系结构 1、单列集合&#xff08;Collection&#xff09; 二、Collection集合 1、Collection常见方法 1.1代码实现&#xff1a; import java.util.ArrayList; import java.util.Collection;public class A01_CollectionDemo1 {public static void main(String[] a…...

TS项目实战二:网页计算器

使用ts实现网页计算器工具&#xff0c;实现计算器相关功能&#xff0c;使用tsify进行项目编译&#xff0c;引入Browserify实现web界面中直接使用模块加载服务。   源码下载&#xff1a;点击下载 讲解视频 TS实战项目四&#xff1a;计算器项目创建 TS实战项目五&#xff1a;B…...

MySQL的ACID、死锁、MVCC问题

1 ACID ACID代表原子性&#xff08;atomicity&#xff09;、一致性&#xff08;consistency&#xff09;、隔离性&#xff08;isolation&#xff09;和持久性&#xff08;durability&#xff09;。一个确保数据安全的事务处理系统&#xff0c;必须满足这些密切相关的标准。 原…...

Docker 可视化工具

1、Portainer 概念介绍 Portainer是一款轻量级的应用&#xff0c;它提供了图形化界面&#xff0c;用于方便地管理Docker环境&#xff0c;包括单机环境和集群环境。 Portainer分为开源社区版&#xff08;CE版&#xff09;和商用版&#xff08;BE版/EE版&#xff09;。 Porta…...

【C++】友元:友元函数与友元类

一、友元 友元&#xff08;friend&#xff09;是C中的一种特殊关系&#xff0c;用于在类之间共享访问权限。通过将一个函数或类声明为另一个类的友元&#xff0c;我们可以允许友元访问声明类的非公有成员。 二、友元函数 问题&#xff1a;现在尝试去重载operator<<&am…...

linux之wsl2安装远程桌面

0. 安装后的效果 1. wsl中打开terminal并安装库 sudo apt-get purge xrdp sudo apt install -y xrdp sudo apt install -y xfce4 sudo apt install -y xfce4-goodies 2.优化显示 sudo sed -i s/max_bpp32/#max_bpp32\nmax_bpp128/g /etc/xrdp/xrdp.ini sudo sed -i s/xserverbp…...

如何以管理员身份删除node_modules文件

今天拉项目&#xff0c;然后需要安装依赖&#xff0c;但是一直报错&#xff0c;如下&#xff1a; 去搜这个问题会让把node_modules文件先删掉 再去安装依赖。我在删除的过程中会说请以管理员身份来删除。 那么windows如何以管理员身份删除node_modules文件呢&#xff1f; wi…...

【Linux】环境基础开发工具的使用之gdb详解(三)

前言&#xff1a;上一篇文章中我们讲解了Linux下的gcc与g的使用&#xff0c;今天我们将进一步的学习gdb与makefile来帮我们更好的理解与使用基础开发工具。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:Linux的深度刨析 &#x1f448; …...

SpringBoot源码解读与原理分析(二十四)IOC容器的刷新(五)

文章目录 7.11 初始化所有剩下的单实例bean对象7.11.1 beanFactory.preInstantiateSingletons7.11.2 getBean7.11.2.1 别名的解析处理7.11.2.2 判断是否已注册过7.11.2.3 创建前的检查7.11.2.4 标记准备创建的bean对象7.11.2.5 合并BeanDefinition7.11.2.6 bean对象的创建7.11.…...

最大子数组和

一、题目 给你一个整数数组nums&#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。子数组 是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 输出&#…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...

起重机起升机构的安全装置有哪些?

起重机起升机构的安全装置是保障吊装作业安全的关键部件&#xff0c;主要用于防止超载、失控、断绳等危险情况。以下是常见的安全装置及其功能和原理&#xff1a; 一、超载保护装置&#xff08;核心安全装置&#xff09; 1. 起重量限制器 功能&#xff1a;实时监测起升载荷&a…...