01_Spring开胃菜
一、 为什么是Spring?
在正式进入Spring内容前我们先看看我们以往经典的程序设计。

当我们去登录时,会调用后端的Controller,Controller接收到用户的请求后会调用业务层的Service进行登录的业务处理,Service业务处理过程中会调用Dao层向DB获取数进行判断。
接下来我们用代码来模拟实现这个逻辑
Controller中,我们需要有一个方法来接收用户发起的请求
public class UserController {private UserService userService = new UserServiceImpl();// 登录public void login() {String username = "admin";String password = "123456";boolean success = userService.login(username, password);System.out.println(success ? "登录成功" : "登录失败");}
}
Service中要进行用户校验的业务逻辑处理,定义Service接口以及实现类
public interface UserService {boolean login(String username, String password);
}
public class UserServiceImpl implements UserService {private UserDao userDao = new UserDaoImplForMySQL();@Overridepublic boolean login(String username, String password) {User user = userDao.findUserByUsernameAndPassword(username, password);return user != null;}
}
Dao中我们要使用用户传过来的用户名和密码去数据库查询是否存在,定义Dao接口及实现类
public interface UserDao {User findUserByUsernameAndPassword(String username, String password);
}
public class UserDaoImplMySQL implements UserDao {@Overridepublic User findUserByUsernameAndPassword(String username, String password) {// 省略具体的实现过程...return null;}
}
看上去这个模拟的实现没有什么问题,但是有一天项目组说我们现在数据从MySQL迁移到了Oracel,怎么办??你得考虑它用户数据未来还会不会迁移回来呢!
所以此时我们就会对于Dao的实现再加一个
// 使用Oracle数据库实现UserDao
public class UserDaoImplForOracle implements UserDao {@Overridepublic User findUserByUsernameAndPassword(String username, String password) {// 省略具体实现过程...return null;}
}
不同的数据库实现有不同的处理方式,感觉逻辑正常,但是这时我们还得要反回去修改Service的实现,让它引用的是新的Dao实现。
public class UserServiceImpl implements UserService {// private UserDao userDao = new UserDaoImpl();private UserDao userDao = new UserDaoImplForOracle(); @Overridepublic boolean login(String username, String password) {User user = userDao.findUserByUsernameAndPassword(username, password);return user != null;}
}
以上的这个设计好吗?实际是不好的,因为每次底层的变化都会要求上层进行代码的变更,其实这里违背软件开发中的开闭原则!
什么是开闭原则?
在软件开发过程中应对扩展开放,对修改关闭。也就是说,如果进行功能扩展时,添加额外的类是没有问题的,但是如果因为功能扩展而修改之前运行正常的程序,这时忌讳,是不被允许的。
从上图可以看出,上层是依赖下层的。UserController依赖UserServiceImpl,则UserServiceImpl依赖UserDaoImplForMySQL,这样就会导致一旦下层的改动,上层必然受到影响也需要进行改动,这也同时违背了另一个开发原则:依赖倒置原则
什么是依赖倒置原则?
依赖倒置原则,简称DIP,主要倡导的是面向抽象编程、面向接口编程,不要面向具体编程,让上层不再依赖下层,这样的话下面改动了,上面代码也不会受到牵连。这可以大大地降低程序的耦合度,耦合度低了扩展性就强了,同时代码的复用性也会增强。
在前面
相关文章:
01_Spring开胃菜
一、 为什么是Spring? 在正式进入Spring内容前我们先看看我们以往经典的程序设计。 当我们去登录时,会调用后端的Controller,Controller接收到用户的请求后会调用业务层的Service进行登录的业务处理,Service业务处理过程中会调用Dao层向DB获取数进行判断。 接下来我们用代…...
SpringBoot使用AspectJ的@Around注解实现AOP全局记录接口:请求日志、响应日志、异常日志
Spring 面向切面编程(AOP),系列文章: 《Spring面向切面编程(AOP)的简单实例》 《Spring使用AspectJ的注解式实现AOP面向切面编程》 《SpringBoot使用AspectJ实现AOP记录接口:请求日志、响应日志、异常日志》 《SpringBoot使用AspectJ的@Around注解实现AOP全局记录接口:…...
WPF下播放Rtmp的解决方案
介绍 在实际的开发过程中,需要在应用内部内嵌播放器进行视频的播放。官方默认的MediaElement控件只能播放有限的视频格式,也不能播放网络流。比较流行的解决方式是vlc的库,但是在实际使用过程中发现有很多问题。这里给大家推荐另一个比较好的…...
7.高可用集群架构Keepalived双主热备原理
一. 高可用集群架构Keepalived双主热备原理 (1)主机+备机keepalived配置(192.168.1.171) ! Configuration File for keepalivedglobal_defs {# 路由id:当前安装keepalived节点主机的标识符,全局唯一router_id keep_101 } #计算机节点(主机配置) vrrp_instance VI_1 {</...
为以人工智能为中心的工作负载重新设计的全局控制台
MinIO 控制台多年来一直是一个不断发展的产品。每次学习时,我们都会思考如何改进交互框架中这个非常重要的部分。首先是控制台,它在推出后的一年内就被广泛采用。更具体地说,超过 10K 个组织。接下来是企业控制台。这从对象存储与其 GUI 之间…...
go channel中的 close注意事项 range取数据
在使用 Go 语言中的 close 函数时,有一些注意事项需要牢记,以确保程序的健壮性和正确性: 1. **仅用于通道(channel)**: - close 函数只能用于关闭通道,不能用于关闭文件、网络连接或其他资源…...
Vue3 -- 项目配置之eslint【企业级项目配置保姆级教程1】
下面是项目级完整配置1➡eslint:【吐血分享,博主踩过的坑你跳过去!!跳不过去?太过分了给博主打钱】 浏览器自动打开项目: 你想释放双手吗?你想每天早上打开电脑运行完项目自动在浏览器打开吗&a…...
鸿蒙开发应用权限管理
简介 一种允许应用访问系统资源(如:通讯录等)和系统能力(如:访问摄像头、麦克风等)的通用权限访问方式,来保护系统数据(包括用户个人数据)或功能,避免它们被…...
【数据库】如何保证数据库迁移过程中数据的一致性?
在数据库迁移过程中,保证数据的一致性是非常重要的,尤其是在涉及到多个表、多个数据库或分布式系统的情况下。以下是一些确保数据一致性的最佳实践和方法: 1. 备份数据 在开始迁移之前,进行全面的数据备份是确保数据一致性的第…...
C++之内存管理
🌹个人主页🌹:喜欢草莓熊的bear 🌹专栏🌹:C入门 目录 前言 一、C/C内存分配 二、 malloc、calloc、realloc、free 三、C内存管理方式 3.1 new/delete 操作内置类型 3.2 new和detele操作自定义类型…...
ISP是什么?
isp全称为Internet Service Provider,即互联网服务提供商,是一种向用户提供互联网接入服务的公司或组织,它们提供的服务包括互联网接入、域名注册、网站托管等等。 ISP的应用场景非常广泛,几乎所有的互联网用户都需要通过ISP来接…...
机房动环境监控用各种列表已经淘汰了,现在都是可视化图表展示了
在信息技术飞速发展的今天,机房作为数据存储、处理和传输的核心场所,其稳定运行至关重要。过去,机房动环境监控主要依赖各种列表形式来呈现数据,但如今,这种方式已经逐渐被淘汰,取而代之的是更加直观、高效…...
RHCE的练习(12)
写一个脚本,完成以下要求: 给定一个用户: 如果其UID为0,就显示此为管理员;否则,就显示其为普通用户; #!/bin/bash # 使用read命令获取用户名 read -p "请输入用户名: " username …...
uniapp自动注册机制:easycom
传统 Vue 项目中,我们需要注册、导入组件之后才能使用组件。 uniapp 框架提供了一种组件自动注册机制,只要你在 components 文件夹下新建的组件满足 /components/组件名/组件名.vue 的命名规范,就能直接使用。 注意:组件的文件夹…...
【论文阅读】(Security) Assertions by Large Language Models
论文笔记:(Security) Assertions by Large Language Models 来源:IEEE TRANSACTIONS ON INFORMATION FORENSICS AND SECURITY I. 引言 计算机系统的安全性通常依赖于硬件的根信任。硬件漏洞可能对系统造成严重影响,因此需要支持安全验证的技术。断言验证是一种流行的验证…...
C++ 编程基础(5)类与对象 | 5.8、面向对象五大原则
文章目录 一、面向对象五大原则1、单一功能(Single Responsibility Principle, SRP)2、开放封闭原则(Open/Closed Principle, OCP)3、里氏替换原则(Liskov Substitution Principle, LSP)4、接口隔离原则&am…...
node.js中express的基本了解
定义 Express是基于Node.js平台,快速、开放、极简的Web开发框架。 本质 Express是一个npm上的第三方包,提供了快速创建Web服务器的便捷方法。 作用 与Node.js内置的http模块类似,Express也是专门用来创建Web服务器的,但它极大地简…...
AI大模型(一):Prompt AI编程
一、Prompt Engineering,提示工程 提示工程也叫指令工程: Prompt是发给大模型的指令,比如【讲个睡前故事】、【用Python写个消消乐游戏】等;本质上大模型相关的工程工作,都是围绕prompt展开的;提示工程门…...
ArcGIS Pro属性表乱码与字段名3个汉字解决方案大总结
01 背景 我们之前在使用ArcGIS出现导出Excel中文乱码及shp添加字段3个字被截断的情况,我们有以下应对策略: 推荐阅读:ArcGIS导出Excel中文乱码及shp添加字段3个字被截断? 那如果我们使用ArGIS Pro出现上述问题,该如何…...
小程序-基于java+SpringBoot+Vue的驾校预约平台设计与实现
项目运行 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
shell脚本质数判断
shell脚本质数判断 shell输入一个正整数,判断是否为质数(素数)shell求1-100内的质数shell求给定数组输出其中的质数 shell输入一个正整数,判断是否为质数(素数) 思路: 1:1 2:1 2 3:1 2 3 4:1 2 3 4 5:1 2 3 4 5-------> 3:2 4:2 3 5:2 3…...
spring boot使用HttpServletResponse实现sse后端流式输出消息
1.以前只是看过SSE的相关文章,没有具体实践,这次接入AI大模型使用到了流式输出,涉及到给前端流式返回,所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...
mcts蒙特卡洛模拟树思想
您这个观察非常敏锐,而且在很大程度上是正确的!您已经洞察到了MCTS算法在不同阶段的两种不同行为模式。我们来把这个关系理得更清楚一些,您的理解其实离真相只有一步之遥。 您说的“select是在二次选择的时候起作用”,这个观察非…...
break 语句和 continue 语句
break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行 break break语句用于跳出代码块或循环 1 2 3 4 5 6 for (var i 0; i < 5; i) { if (i 3){ break; } console.log(i); } continue continue语句用于立即终…...
Centos 7 服务器部署多网站
一、准备工作 安装 Apache bash sudo yum install httpd -y sudo systemctl start httpd sudo systemctl enable httpd创建网站目录 假设部署 2 个网站,目录结构如下: bash sudo mkdir -p /var/www/site1/html sudo mkdir -p /var/www/site2/html添加测试…...
