SSM阶段性总结

news2025/4/18 5:03:34

0 Pojo类

前端给后端:DTO

后端给前端:VO

数据库:PO/VO

业务处理逻辑:BO

统称pojo

1 代理模式


实现静态代理:

  • 1定义接口
  • 2实现类
  • 3写一个静态代理类
  • 4这样在调用时就可以使用这个静态代理类来实现某些功能

实现动态代理

  • 1实现接口
  • 2实现类
  • 3写一个动态代理模块
  • 4可以使用通用方法(直接强转)
  • 实现AOP切面编程

2 事务

事务四大特性(ACID)

  1. 原子性

    • 定义:事务是最小操作单元,要么全部成功,要么全部失败回滚。

    • 关键点:不存在“部分成功”,如转账时扣款和加款必须同时完成或撤销。

  2. 一致性

    • 定义:事务完成后,数据必须满足业务规则(如账户余额不为负)。

    • 关键点:通过原子性、隔离性、持久性共同保障最终一致性。

  3. 隔离性

    • 定义:并发事务之间互不干扰,避免脏读、不可重复读、幻读。

    • 关键点:通过隔离级别(如 READ_COMMITTED)控制并发影响。

  4. 持久性

    • 定义:事务提交后,数据永久保存,即使系统故障也不丢失。

    • 关键点:依赖数据库持久化机制(如日志、磁盘存储)。


事务隔离问题与解决方案

  1. 脏读

    • 现象:读到其他事务未提交的数据(若事务回滚则数据无效)。

    • 解决READ_COMMITTED 级别,仅读取已提交的数据。

  2. 不可重复读

    • 现象:同一事务多次读取同一数据,结果不一致(因其他事务修改)。

    • 解决REPEATABLE_READ 级别,锁定已读数据禁止修改。

  3. 幻读

    • 现象:同一事务中查询结果集数量变化(因其他事务增删数据)。

    • 解决SERIALIZABLE 级别,锁定整表禁止增删。


事务管理方式

  1. 声明式事务

    • 实现:通过 @Transactional 注解或 XML 配置。

    • 优点:代码简洁,无侵入性。

    • 缺点:调试困难(异常可能被代理包装)。

  2. 编程式事务

    • 实现:手动编码控制事务(如 TransactionTemplate)。

    • 优点:灵活,可精细控制事务边界。

    • 缺点:代码冗余,侵入性强。


Spring 开启事务的步骤

  1. 启用事务管理

    • 在配置类添加 @EnableTransactionManagement,启用注解驱动事务。

  2. 配置事务管理器

    • 定义 PlatformTransactionManager Bean(如 DataSourceTransactionManager)。

  3. 标记事务方法

    • 在 Service 方法或类上添加 @Transactional,指定隔离级别、传播行为等属性。


3 IOC/MVC/AOP三个概念在Spring中的理解

IOC(控制反转)Inversion of Control

核心思想:将对象的创建和依赖管理权交给 Spring 容器,实现解耦。

  • 控制:对象创建的控制权。

  • 反转:从手动 new 对象,转为由容器自动注入(如 @Autowired)。
    实现方式

  • 依赖注入(DI)Dependency Injection:通过构造函数、Setter 方法或注解自动装配依赖。

  • 容器管理:Spring IoC 容器(如 ApplicationContext)负责对象的生命周期和依赖关系。
    通俗类比

点外卖时,你只需下单(声明需要什么对象),平台(Spring 容器)负责调度餐厅(创建对象)和配送(注入依赖)。


MVC(Model-View-Controller)

核心思想:分离业务逻辑、数据和显示,提升代码可维护性。

  • Model(模型):封装业务数据和逻辑(如 ServiceDAO 层)。

  • View(视图):负责数据展示(如 JSP、Thymeleaf 模板)。

  • Controller(控制层):接收请求,调用模型处理,返回视图(如 @Controller 注解的类)。
    Spring MVC 流程

  1. 用户请求 → DispatcherServlet(前端控制器)

  2. 根据 URL 路由 → 调用对应 Controller

  3. Controller 调用 Service 处理业务 → 返回数据(Model)

  4. ViewResolver 解析视图 → 渲染结果返回用户。
    通俗类比

Spring MVC 下我们一般把后端项目分为 Service 层(处理业务)、Dao 层(数据库操作)、Entity 层(实体类)、Controller 层(控制层,返回数据给前台页面)。

餐厅中,服务员(Controller)接收订单,交给厨师(Model)做菜,最后由传菜员(View)端给顾客。


AOP(面向切面编程)Aspect Oriented Programming

核心思想:将横切关注点(与业务无关,日志,事务等)从核心业务中分离出来,形成一个个的切面,实现模块化,减少代码冗余。
实现技术

  1. 动态代理(Spring AOP 默认):

    • JDK 动态代理:基于接口生成代理对象(要求目标类实现接口)。

    • CGLIB 代理:通过继承生成子类代理(可代理无接口的类)。

  • 日志记录、事务管理(@Transactional)、权限校验、性能监控。
    通俗类比

咖啡师(核心业务)专注做咖啡,助手(切面)自动处理记录订单、清洁机器等杂务。


JDK动态代理:

是去动态的生成一个代理对象,其中有一个操作类Proxy,方法newProxyInstance

三个参数:

1 类加载器ClassLoader:目的将动态代理的对象加载到我们的JVM虚拟机

2 接口的集合:指的是我们要代理哪一个接口(这也是我们动态代理的一个特征,只能基于我们的接口去代理)

3 invocationHandler代理拦截(拦截器)当需要调用动态代理的一个对象的方法的时候,会走到代理器当中invoke方法,(代理的对象,调用的方法的名字,参数)传递过来,在方法中添加需要添加的代理方法实现动态代理的过程


三者的协作关系

  1. IOC 容器:管理所有对象(包括 MVC 的 Controller、Service 和 AOP 的代理对象)。

  2. MVC:处理 Web 请求时,依赖 IOC 容器注入 Service 和 Dao。

  3. AOP:通过代理对象增强 Service 层方法(如添加事务),而这一切由 IOC 容器动态组装。


4 @Component注解与@Bean注解

@Component注解是作用在类上的,通过@Component注解Spring会自动创建该类的实例注入到SpringIOC容器中,

@Bean注解是用于配置类中声明一个Bean的,通常是用在配置类的方法上,表示把这个方法的返回对象注册到SpringIOC容器当中,通过这个注解我们可以自定义Bean的创建和初始化过程,包括指定Bean的名称、作用域、依赖关系等


核心区别

1. 用途不同:@Component通常用于标识一个普通的类,而@Bean用于配置类中的Bean对象,通常结合@Configuration进行使用。

2. 使用方式不同:@Component是类级别的注解,Spring可以扫描到被此注解标注的类并把它们注入到Spring容器中。@Bean是修饰在方法上的,表示此方法返回一个Bean对象注入到Spring容器中。

3. 控制权不同:@Component标注的类是由Spring框架来统一管理和创建的,而@Bean允许开发人员手动控制Bean的创建和配置。


5 Spring推荐使用构造器注入的原因

1 依赖完整性:确保所有必须依赖在对象创建时就被注入,避免了空指针异常的风险。

2 不可变性:有助于创建不可变对象(支持final字段),提高了线程安全性。

3 初始化保证:组件在使用前就已完成了初始化,减少了潜在的错误。

4 测试遍历性:在单元测试中可以通过构造函数传入模拟的依赖项,而不必依赖Spring 容器进行注入

依赖注入的选择策略

  • 强制依赖:优先使用构造器注入(确保依赖非空、对象不可变、完全初始化,推荐默认使用)。

  • 可选依赖:使用 Setter 注入 或配置方法(可为依赖提供默认值,支持后续重新配置,如配置项、动态代理对象)。

public class OrderService {
    // 强制依赖(通过构造器注入)
    private final PaymentService paymentService;
    // 可选依赖(通过Setter注入)
    private DiscountService discountService;

    // 构造器注入(强制依赖)
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    // Setter注入(可选依赖)
    public void setDiscountService(DiscountService discountService) {
        this.discountService = discountService;
    }

}
@RequiredArgsConstructor生成包含 final 或 @NonNull 字段的构造方法

6 SpringMVC

三层架构

1 Dao层:实现对数据库的操作

2 Service:业务层一些逻辑关系

3 Controller:处理http请求

简单的使用

声明(表明@RestController注解=@Controller+@ResponseBody这两个注解)

在传递参数时我们有两种传递方式1使用参数一一传递 2使用对应的封装对象POJO)

获取请求头@RequestHeader用这个注解提取HTTP请求传递的指定参数值

获取Cookie值@CookieValue从 HTTP 请求的 Cookie 头中获取指定名称的 Cookie 值。

url:Uniform Resource Identifier 统一资源标识符


7 Restful软件架构风格 资源表现层状态转移

Resource Representational State Transfer

核心:API的设计原则

RESTful = 用资源地址(URI) + 标准动作(HTTP方法) + 明确状态码(2xx/4xx/5xx)

用 HTTP 方法(GET/POST/PUT/DELETE 等)表示“动作”

用 URL 表示“资源” (信息)

RESTful 的 HTTP 方法:用 GET 查、POST 增、PUT/PATCH 改、DELETE 删,动作在方法里,资源在地址里。

URL vs. HTTP 方法的分工

动作HTTP 方法URL 示例说明
获取所有用户GET/users列表用复数名词
获取单个用户GET/users/123用 ID 定位单个资源
创建用户POST/users资源集合 URL + POST
更新用户PUT/users/123用 ID 定位 + PUT
删除用户DELETE/users/123用 ID 定位 + DELETE

客户端 → HTTP 请求(RESTful 接口) → Controller 层 → Service 层 → Dao 层 → 数据库
                  ↑                                  ↑
             协议处理(RESTful)               业务逻辑与数据操作(分层架构)

对比:RESTful vs 非RESTful

场景RESTful 示例非RESTful 反例
获取用户GET /users/123POST /getUser?id=123
创建订单POST /ordersGET /createOrder
更新资料PUT /users/123POST /updateUser
错误响应404 Not Found200 OK { "code": 404 }

8 拦截器

作用对象controller

1 定义一个类实现HandlerInterceptor接口的组件(定义基础方法)preHandke=>目标方法=>postHandle=>afterCompletion

2 再定义一个类实现WebMvcConfigurer(指定拦截路径)


9 异常

主要是利用声明式异常处理@ExceptionHandler(异常类型)对方法进行声明

但是为了方便我们可以使用全局异常处理

在类上声明@ControllerAdvice+@ResponseBoby=@RestControllerAdvice

在类上再使用@ExceptionHandler


10 数据校验

需要参数绑定(指定需要校验的数据),校验失败就会抛出异常

将异常交给全局异常处理器,编写代码将校验失败抛出的异常捕获,接收校验参数,将校验结果返回并反馈。

分组校验:

分组校验确实提供了更大的灵活性,可以根据不同的业务场景为不同的字段设置不同的校验规则

分组校验可以根据需求设置组别,比如说在登录时需要一个NotNull但是注册时不需要这个一个校验,那我们就可以在不需要的校验参数groups中不加对应的组,需要就加上组别,最后具体实现的时候在@Validdated中声明对应的组别即可实现更加灵活的校验帮我组织语言

不使用分组校验:

在类中声明时使用的是@Valid导致的是将传递的对象的参数所有都进行校验,但是使用分组校验则可以自己控制校验的数据(在自己需要校验的字段中的groups中指定即可)

在分组校验中,如果某个字段没有被指定到特定的分组,那么在使用该分组进行校验时,该字段将不会被校验。然而,这并不会影响该字段的数据传递。也就是说,即使 email 字段没有被指定到 LoginGroup 分组,email 参数仍然会正常传递到方法中,只是不会对其进行校验。


11 VO

VO(值对象)的核心作用是为前端提供安全、精简的数据视图。

我们需要根据需求设置一个不同于原先的Bean类,将需要脱敏的数据隐藏,在查询等方法的方法内部编写需要的程序,利用BeanUtils.copyProperties完成基础属性拷贝后,可针对性实现数据脱敏


12 Maven

核心配置:GAVP:GroupId、ArttifactId、Version、Packaging(scope依赖的作用范围)

生命周期:编译,运行测试,打包,安装到本地,部署到远程

  • 依赖传递特性:自动引入直接依赖的间接依赖,简化配置,但可能引发版本冲突
  • 依赖冲突特性:路径最近优先和声明顺序优先,先声明优先,路径短优先。
  • 工程继承聚合:
  1. 继承:子模块复用父POM的配置(依赖/插件/版本),统一管理。

  2. 聚合:通过父POM的 <modules> 批量构建多个子模块,实现一键多模块协作。

父模块声明版本号即可,子模块可不声明

13 自动配置

自动配置是Spring的一大特性,其会在底层将一些配置信息自动配置。

选择starter依赖Springboot会自动引入场景的所有依赖,其会导入spring-boot-autoconfiguration自动配置包里面的文件中包含所有的配置信息

调用是通过主程序的@Adpplication注解,其包含三个注解

一个是@ComponentScan组件扫描

一个是@SpringBootConfiguration标识为配置类

一个是@EnableAutoConfiguration启动自动配置的核心开关

里面有一个@import(AutoConfigurationImportSelector.class),这里会导入自动配置类从之前的依赖导入的jar包中寻找配置信息

自动配置类XxxAutoConfiguration会根据@Conditional条件注解进行使用

自动配置类是如何配置:

自动配置类在依赖导入的jar包当中已经封装好,

配置类当中会有一个注解@EnableConfigurationProperties

会开启属性配置(属性与配置文件的绑定),属性类会从配置文件当中获取信息,

属性类当中还有一个@ConfigurationProperties注解用于获取配置文件当中配置信息进行匹配(以什么为开头)

自动配置类通常用@Configuration和@ConditionalOnXXX注解,当条件满足时,会创建相应的Bean。这些自动配置类可能依赖属性类,这些属性类通过@ConfigurationProperties绑定配置文件中的属性。

  1. 正确点

    • 配置信息的最终来源相同(外部配置文件)。

    • 若用户未手动创建Bean,Spring自动配置生效;若用户定义Bean,优先使用用户定义。

  2. 需补充点

    • 手动配置不一定依赖属性类:开发者可以选择更灵活的配置注入方式(如 @Value),但推荐使用属性类以保持结构化和类型安全。(@Value(“¥{指定路径进行获取}))

    • 自动配置强制使用属性类:这是Spring Boot设计上的一致性要求,确保配置管理的标准化。

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

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

相关文章

Qt 5.14.2入门(一)写个Hello Qt!程序

目录 参考链接&#xff1a;一、新建项目二、直接运行三、修改代码增加窗口内容1、Qt 显示一个 QLabel 标签控件窗口2、添加按键 参考链接&#xff1a; Qt5教程&#xff08;一&#xff09;&#xff1a;Hello World 程序 Qt 编程指南 一、新建项目 1、新建一个项目&#xff08…

Jmeter分布式测试启动

代理客户端配置 打开jmeter.properties文件&#xff0c;取消注释并设置端口&#xff08;如server_port1099&#xff09;&#xff0c; 并添加server.rmi.ssl.disabletrue禁用SSL加密。 &#xff08;Linux系统&#xff09;修改jmeter-server文件中的RMI_HOST_DEF为代理机实际IP。…

redis itheima

缓存问题 核心是如何避免大量请求到达数据库 缓存穿透 既不存在于 redis&#xff0c;也不存在于 mysql 的key&#xff0c;被重复请求 public Result queryById(Long id) {String key CACHE_SHOP_KEYid;// 1. redis & mysqlString shopJson stringRedisTemplate.opsFo…

100天精通Python(爬虫篇)——第122天:基于selenium接管已启动的浏览器(反反爬策略)

文章目录 1、问题描述2、问题推测3、解决方法3.1 selenium自动启动浏览器3.2 selenium接管已启动的浏览器3.3 区别总结 4、代码实战4.1 手动方法&#xff08;手动打开浏览器输入账号密码&#xff09;4.2 自动方法&#xff08;.bat文件启动的浏览器&#xff09; 1、问题描述 使用…

MPP 架构解析:原理、核心优势与对比指南

一、引言&#xff1a;大数据时代的数据处理挑战 全球数据量正以指数级增长。据 Statista 统计&#xff0c;2010 年全球数据量仅 2ZB&#xff0c;2025 年预计达 175ZB。企业面临的核心挑战已从“如何存储数据”转向“如何快速分析数据”。传统架构在处理海量数据时暴露明显瓶颈…

Python设计模式-工厂模式

一、模式定义与核心思想 工厂模式&#xff08;Factory Pattern&#xff09;属于创建型设计模式&#xff0c;其核心思想是通过一个"工厂类"来创建对象&#xff0c;而不是直接调用类的构造函数。这种模式将对象的实例化过程封装起来&#xff0c;使系统在实例化对象时能…

彻底解决VS2008编译错误:fatal error C1083 无法打开包括文件“stdint.h“

彻底解决VS2008编译错误&#xff1a;fatal error C1083 无法打开包括文件"stdint.h" 一、错误现象与本质原因 当在Visual Studio 2008中编译包含C99标准整数类型&#xff08;如int8_t、uint32_t&#xff09;的代码时&#xff0c;常出现以下编译错误&#xff1a; f…

react从零开始的基础课

全文约5万字。 1.hello,.. // App.jsx import { useState } from react import reactLogo from ./assets/react.svg import viteLogo from /vite.svg import ./App.cssfunction App() {const [count, setCount] useState(0)return (<><Greeting name"world&qu…

算法题型讲解

一.双指针 主要分为俩种类型&#xff1a; 1.左右指针&#xff1a;双指针指向开头&#xff0c;以一定标准移动或交换&#xff0c;对区域进行划分&#xff0c;或找到特殊点的位置 &#xff08;如&#xff1a;快慢指针判断有无环&#xff0c;移动零&#xff09; 2.对撞指针&am…

Redis和数据库一致性问题

操作模拟 1、先更新数据库还是先更新缓存&#xff1f; 1.1先更新缓存&#xff0c;再更新数据库 按并发的角度来说&#xff0c;有两个线程A、B&#xff0c;操作同一个数据&#xff0c;线程A先更新缓存为1&#xff0c;在线程A更新数据库之前&#xff0c;这时候线程B进来&#…

第R8周:RNN实现阿尔茨海默病诊断(pytorch)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 本人往期文章可查阅&#xff1a; 深度学习总结 一、准备工作 &#x1f3e1; 我的环境&#xff1a; 语言环境&#xff1a;Python3.1…

C++基础精讲-02

文章目录 1.C/C申请、释放堆空间的方式对比1.1C语言申请、释放堆空间1.2C申请、释放堆空间1.2.1 new表达式申请数组空间 1.3回收空间时的注意事项1.4malloc/free 和 new/delete 的区别 2.引用2.1 引用的概念2.2 引用的本质2.3 引用与指针的联系与区别2.4 引用的使用场景2.4.1 引…

【网络安全】Linux 命令大全

未经许可,不得转载。 文章目录 前言正文文件管理文档编辑文件传输磁盘管理磁盘维护网络通讯系统管理系统设置备份压缩设备管理其它命令前言 在网络安全工作中,熟练掌握 Linux 系统中的常用命令对于日常运维、日志分析和安全排查等任务至关重要。 以下是常用命令的整理汇总,…

C++学习之ORACLE①

目录 1.ORACLE数据库简介 2..ORACLE数据库安装 3..ORACLE体系结构 4..ORACLE基本概念 5..ORACLE基本元素 6..ORACLE数据库启动和关闭 7.SQLPLUS登录ORACLE数据库相关操作 8.SQLPLUS的基本操作 9.oracle中上课使用的方案 10.SQL语言分类 11.SQL中的select语句语法和注…

企业级开发SpringBoost玩转Elasticsearch

案例 Spring Boot 提供了 spring-data-elasticsearch 模块&#xff0c;可以方便地集成 Elasticsearch。 下面我们将详细讲解如何在 Spring Boot 中使用 Elasticsearch 8&#xff0c;并提供示例代码。 1. 添加依赖: 首先&#xff0c;需要在 pom.xml 文件中添加 spring-data-e…

从零开始的图论讲解(1)——图的概念,图的存储,图的遍历与图的拓扑排序

目录 前言 图的概念 1. 顶点和边 2. 图的分类 3. 图的基本性质 图的存储 邻接矩阵存图 邻接表存图 图的基本遍历 拓扑排序 拓扑排序是如何写的呢? 1. 统计每个节点的入度 2. 构建邻接表 3. 将所有入度为 0 的节点加入队列 4. 不断弹出队头节点&#xff0c;更新其…

SpringBoot框架—启动原理

1.SpringBootApplication注解 在讲解启动原理之前先介绍一个非常重要的注解SpringBootApplication&#xff0c;这个注解在Springboot程序的入口文件Application.java中必须添加。SpringBootApplication是一个整合了三个核心注解的组合注解。 三个核心注解的作用机制&#xff1…

怎么检查网站CDN缓存是否生效

为什么要使用CDN缓存&#xff1f; 网站使用缓存可显著提升加载速度&#xff0c;减少服务器负载和带宽消耗&#xff0c;优化用户体验&#xff0c;增强架构稳定性&#xff0c;助力SEO优化&#xff0c;实现资源高效利用与性能平衡。 通过合理配置 CDN 缓存策略&#xff0c;可降低…

【自然语言处理】深度学习中文本分类实现

文本分类是NLP中最基础也是应用最广泛的任务之一&#xff0c;从无用的邮件过滤到情感分析&#xff0c;从新闻分类到智能客服&#xff0c;都离不开高效准确的文本分类技术。本文将带您全面了解文本分类的技术演进&#xff0c;从传统机器学习到深度学习&#xff0c;手把手实现一套…

vba讲excel转换为word

VBA将excel转换为word Sub ExportToWordFormatted() 声明变量Dim ws As Worksheet 用于存储当前活动的工作表Dim rng As Range 用于存储工作表的使用范围&#xff08;即所有有数据的单元格&#xff09;Dim rowCount As Long, colCount As Long 用于存储数据范围的行数和列数…