10大 spring源码设计模式 (图解+秒懂+史上最全)

本文 的 原文 地址

原始的内容,请参考 本文 的 原文 地址

本文 的 原文 地址

尼恩说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团、蚂蚁、得物的面试资格,遇到很多很重要的相关面试题:

说下spring中常用的设计模式?

谈谈Spring用到了哪些设计模式?

说一下spring的架构,使用的设计模式

最近有小伙伴在面 蚂蚁,问到了相关的面试题,可以说是逢面必问。

小伙伴没有系统的去梳理和总结,所以支支吾吾的说了几句,面试官不满意,面试挂了。

所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

最终,机会爆表,实现”offer自由” 。

当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V175版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到文末公号【技术自由圈】获取

本文作者:

  • 第一作者 老架构师 肖恩(肖恩 是尼恩团队 高级架构师,负责写此文的第一稿,初稿 )
  • 第二作者 老架构师 尼恩 (45岁老架构师, 负责 提升此文的 技术高度,让大家有一种 俯视 技术、俯瞰技术、 技术自由 的感觉

后面还有很多的真题要发布。

注意:Spring 能 暴击面官的不到10%

Spring 的源码 非常重要,但是 很多人 , 在死记硬背。

90%的人回答不到 Spring 的源码 底层思维的 点,能 暴击面官的不到10%

这张饼图揭示了一个残酷但真实的现状:

在 Spring 源码的学习生态中,真正掌握其底层设计思维的人仅占10%。

这10%往往正是各大厂争抢的核心人才——他们不仅能读懂源码,更能从中提炼出通用的设计模式与架构原则,并迁移到自己的项目实践中。

中间80%的群体,虽然投入时间阅读过源码,但由于缺乏问题驱动的学习方式和系统化的归纳能力,最终陷入“看时明白,用时遗忘”的怪圈。

剩下的10%尚未触碰源码的开发者,则更多依赖文档和教程堆砌功能实现,在面对复杂问题时缺乏根因分析的能力。

这一分布也提醒我们:看源码不是目的,构建可迁移的架构思维才是关键。

跟着45岁老架构,一步一步 构建可迁移的架构思维.

一、 spring 架构 的介绍

Spring 框架采用高度模块化的架构设计,各个模块可以独立使用,也可以组合使用。

其核心是IoC容器,所有其他功能都构建在它之上。无论是 Bean 的创建、配置、生命周期管理,还是 AOP 的织入、事务的代理、Web 请求的调度,背后都是 IoC 容器在驱动。

可以说,没有 IoC,就没有 Spring 的一切高级能力

1.1、Spring 架构分层总览

接下来这张分层图,就是我们理解 Spring 全局架构的“地图”。

它不仅展示了模块之间的纵向依赖关系,也揭示了功能演进的内在逻辑:


┌─────────────────────────────────────────────────────────────────┐
│                   应用层 (Application Layer)                     │
│   用户业务代码、自定义配置、应用特定功能                               │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│                   数据访问/集成层 (Data Access/Integration)       │
│  JDBC │ ORM │ Transactions │ JMS │ OXM                          │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│                   Web层 (Web Layer)                            │
│  Web MVC │ WebFlux │ WebSocket │ Web (Servlet API)             │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│                   AOP层 (AOP Layer)                            │
│  AOP │ Aspects │ Instrumentation                               │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│                   核心容器 (Core Container)                      │
│  Beans │ Core │ Context │ SpEL                                 │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│                   测试层 (Test Layer)                           │
│  spring-test (单元测试、集成测试支持)                           │
└─────────────────────────────────────────────────────────────────┘

为了帮助记忆并快速建立认知模型,尼恩帮大家 引入一个形象化的口诀:“1 根主线 + 4 条支线 + 1 座生态工厂”

这个模型 是对 Spring 实际运行机制的高度抽象。

1 根主线:IoC 主线

位于最底层的核心容器层(Beans│Core│Context│SpEL),构成了 Spring 的主干道——也就是所谓的“1 号线”。这条线路贯穿始终,承载着所有组件的注册、解析、实例化与依赖注入过程。

具体来说:

  • spring-core 提供基础工具类(如 ClassUtils、PropertyEditorRegistry),是整个框架的地基;
  • spring-beans 实现了 BeanDefinition 的定义与 BeanFactory 的基本容器逻辑;
  • spring-context 在 BeanFactory 基础上扩展为 ApplicationContext,增加了事件发布、国际化、资源加载等企业级能力;
  • spring-expression(SpEL)则赋予运行时动态计算的能力,例如 @Value("#{systemProperties.port}") 这类表达式求值。

这四个模块共同组成了 Spring 的“心脏”,任何其他功能若想接入 Spring 容器管理,就必须走通这条主线。

4 条业务支线:功能延伸通道

如果说 IoC 是动脉,那么这些“支线”就是将血液输送到不同器官的静脉网络。

它们各自服务于特定领域,并通过依赖或扩展的方式挂载到主线上。

线路 覆盖楼层 对应官方层 关键词
2 号线 AOP 支线 AOP 层 AOP│Aspects│Instrumentation 横切外挂
3 号线 Data 支线 数据访问/集成层 JDBC│ORM│Transactions│JMS│OXM 模板+事务
4 号线 Web 支线 Web 层 Web MVC│WebFlux│WebSocket│Servlet 前端总闸
5 号线 Test 支线 测试层 spring-test 单元+集成

每条支线都不是孤立存在的:

  • AOP 支线利用代理机制,在不修改源码的前提下增强方法行为,常用于日志、权限、事务控制;
  • Data 支线屏蔽了不同持久化技术(JDBC、Hibernate、MyBatis)的差异,提供统一模板(如 JdbcTemplate)和声明式事务支持;
  • Web 支线作为对外暴露服务的入口,无论是传统 Servlet 容器还是响应式 WebFlux,均由该层统一处理请求流转;
  • Test 支线则打通上下文环境,让开发者可以在接近生产环境的条件下完成集成测试。

这些支线看似平行,实则都深深扎根于 IoC 主线之上——Bean 的代理由容器生成,事务注解由容器解析,MVC 控制器由容器托管,测试上下文由容器加载。脱离容器,它们都将失去灵魂

1 座 生态工厂:出站即达的加速引擎

当基础架构搭建完毕,真正的生产力爆发来自于生态整合。

这里就引出了 Spring 最具革命性的两个衍生项目——它们不是模块,而是“自动化装配工厂”。

  • Spring Boot:给 1 号线和 n 条支线装上了“无人驾驶系统”。通过自动配置(AutoConfiguration)和起步依赖(Starter),它能根据 classpath 自动启用对应模块,极大降低了使用门槛。原本需要手动配置的 DataSource、TransactionManager、DispatcherServlet,现在只需一个 @SpringBootApplication 就能全部搞定。

  • Spring Cloud:在 Boot 的基础上再开一条“城际高速”。它把原本运行在单机上的 Spring 应用,通过服务注册发现(Eureka)、配置中心(Config)、API 网关(Gateway)、熔断限流(Hystrix/Sentinel)等方式,分布式地部署到多个节点上,形成微服务集群。本质上,它是将 Spring 的模块化思想从“进程内解耦”推向“跨进程协作”。

换句话说,Spring 是骨架,Boot 是肌肉,Cloud 是神经系统。三者层层递进,构成了现代 Java 后端开发的事实标准。

1.2、spring 各层详细架构解析

1.2.1. 核心容器 (Core Container)

这是 Spring 框架的基础,提供依赖注入和控制反转功能。

如果说 Spring 是一座大厦,那核心容器就是它的地基与承重墙。它不仅是框架启动的第一站,更是所有高级功能得以运行的前提条件。

在这个层级中,最核心的概念是 IoC 容器,而它的两种典型实现分别是 BeanFactoryApplicationContext。虽然两者都能完成 Bean 的管理和依赖注入,但在定位和能力上有明显差异。


// 核心容器组件关系
┌─────────────────────────────────────────────────────────────┐
│                    ApplicationContext                      │
│  (应用上下文,BeanFactory的超集,添加企业级功能)                  │
└─────────────────────────────────────────────────────────────┘△│ 继承
┌─────────────────────────────────────────────────────────────┐
│                      BeanFactory                            │
│    (Bean工厂,IoC容器基本实现,负责Bean生命周期管理)              │
└─────────────────────────────────────────────────────────────┘△│ 依赖
┌───────────────┐  ┌───────────────┐  ┌─────────────────────┐
│   Core模块     │  │   Beans模块   │  │     SpEL模块         │
│ (基础工具类)    │  │ (Bean定义实现) │  │ (表达式语言支持)       │
└───────────────┘  └───────────────┘  └─────────────────────┘

BeanFactory 是最基础的 IoC 容器接口,提供了延迟加载、作用域控制、依赖查找等核心能力,适合资源受限环境;

ApplicationContext 是其子接口,除了继承所有功能外,还额外支持:

  • 国际化(MessageSource)
  • 事件发布(ApplicationEventPublisher)
  • 资源访问(ResourceLoader)
  • 环境抽象(Environment)
  • 自动注册 BeanPostProcessor 和 BeanFactoryPostProcessor

因此,在实际开发中,我们几乎总是使用 ApplicationContext,尤其是在 Spring Boot 中默认使用的 AnnotationConfigApplicationContextWebApplicationContext

1.2.2. AOP 层 (AOP Layer)

提供面向切面编程支持,实现横切关注点的模块化。

在真实的业务系统中,总会有一些功能像“胶水”一样粘附在多个业务逻辑之间——比如日志记录、性能监控、安全校验、事务控制。如果把这些代码直接写进每个方法里,就会导致严重的重复和污染。这就是典型的横切关注点(Cross-cutting Concerns)

AOP 层的存在,就是为了优雅地解决这个问题。

AOP 层 通过“动态代理 + 切面织入”的方式,将这些通用逻辑从业务代码中剥离出来,形成独立的切面(Aspect),并在运行时无缝嵌入目标方法的执行流程中。


┌─────────────────────────────────────────────────────────────┐
│                    Spring AOP 体系结构                       │
└─────────────────────────────────────────────────────────────┘△
┌─────────────────┬─────────────────┬─────────────────────────┐
│   代理机制       │    切面支持       │    集成扩展               │
├─────────────────┼─────────────────┼─────────────────────────┤
│ • JDK动态代理    │ • @AspectJ注解   │ • AspectJ集成            │
│ • CGLIB字节码   │ • 声明式AOP配置    │ • 自定义切入点              │
│   增强          │ • 五种通知类型     │ • 引入(Introduction)      │
└─────────────────┴─────────────────┴─────────────────────────┘

Spring AOP 分为三个层次:

(1) 代理机制层:决定如何生成代理对象。对于实现了接口的类,使用 JDK 动态代理;对于没有接口的类,则采用 CGLIB 字节码增强技术生成子类代理;

(2) 切面支持层:提供编程模型支持,包括基于 @Aspect 注解的切面定义、五种通知类型(前置、后置、返回、异常、环绕),以及切入点表达式(Pointcut Expression)来精准匹配目标方法;

(3) 集成扩展层:允许与更强大的 AspectJ 工具链集成,支持编译期织入、更复杂的切点语法,甚至可以在字段访问、构造函数调用等场景下触发通知。

注意,Spring AOP 默认采用“运行时织入”,性能损耗可控,且与 IoC 容器深度整合。

例如,@Transactional 注解之所以能在 Service 方法上生效,本质就是 Spring AOP 创建了一个事务代理对象,拦截方法调用并自动开启/提交事务。

1.2.3. Web 层 (Web Layer)

Web 层 支持 Web 应用程序开发。 Web 层就是Spring 的“感官系统”——负责接收外部请求、组织响应数据,是整个应用对外交互的门户。

Spring MVC 是使用最广泛的模块,其请求处理流程体现了典型的“责任链 + 控制反转”设计思想.


┌─────────────────────────────────────────────────────────────┐
│                    Spring MVC 请求处理流程                    │
└─────────────────────────────────────────────────────────────┘△┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐│ 请求进入 │ -> │ 前端控制  │ -> │ 处理器映  │ -> │ 处理器适   ││         │    │  器     │    │  射查找  │    │  配器执行 │└─────────┘    └─────────┘    └─────────┘    └─────────┘△┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐│ 视图解析 │ <- │ 结果处理 │ <- │ 拦截器链  │ <- │ 业务逻辑 ││  渲染   │    │         │    │  执行    │    │  执行   │└─────────┘    └─────────┘    └─────────┘    └─────────┘

整个流程如下:

(1) 请求首先进入 DispatcherServlet(前端控制器),它是整个 MVC 的调度中枢;

(2) 通过 HandlerMapping 查找哪个 Controller 的哪个方法能处理该请求;

(3) 找到后交由 HandlerAdapter 适配执行(兼容不同类型的处理器,如 @RequestMapping 方法、函数式端点等);

(4) 执行过程中会经过 Interceptor 拦截器链,可用于权限检查、日志打印等;

(5) 方法执行完成后返回 ModelAndView 或 ResponseEntity,经 ViewResolver 解析视图并渲染输出。

这一整套流程完全由 Spring 容器驱动,Controller、Service、Repository 都是被 IoC 管理的 Bean,AOP 可以自由切入,事务可以精准控制。

这才是 Spring 全栈能力的真正体现。稍后,会进行更深入的介绍。

1.2.4. 数据访问/集成层 (Data Access/Integration)

提供统一的数据访问抽象,支持多种持久化技术。

而不同的 ORM 框架(如 Hibernate、MyBatis)各有优劣,但直接使用它们容易造成代码冗余、异常混乱、事务难以统一。

Spring 设计了一套统一的数据访问抽象层,旨在屏蔽底层差异,降低开发复杂度,同时提供一致的编程模型和异常体系。


┌──────────────────────────────────────────────────────────────────────┐
│                   数据访问层架构                                       │
└──────────────────────────────────────────────────────────────────────┘┌──────────┐     ┌──────────────────┐  ┌─────────────┐  ┌──────────┐│  用户代码  │    │ 声明式事务         │  │ 数据访问 模板 │  │   ORM    ││ (@Service)│    │ (@Transactional) │  │             │  │   集成层  │└──────────┘     └──────────────────┘  └─────────────┘  └──────────┘△              △┌──────────┐  ┌──────────┐  ┌────────────────┐  ┌───────────┐│ 事务管理  │  │ 统一异常   │  │ JDBC抽象        │  │ Hibernate ││  器      │  │  处理     │  │ (JdbcTemplate) │  │    JPA等   │└──────────┘  └──────────┘  └────────────────┘  └────────────┘

该层的核心价值体现在三个方面:

(1) JDBC 抽象(JdbcTemplate):

原生 JDBC 写起来繁琐且易错(Connection、Statement、ResultSet 需手动关闭)。Spring 提供了 JdbcTemplate,封装了 try-catch-finally 流程,开发者只需关注 SQL 和结果映射,其余交给模板处理。例如一行代码即可完成查询:


List<User> users = jdbcTemplate.query("SELECT * FROM user", new UserRowMapper());

(2) 统一异常体系(DataAccessException):

不同数据库驱动抛出的异常类型各异(SQLException 子类繁多),不利于统一处理。Spring 将所有数据访问异常转换为 DataAccessException 的继承体系,且均为非检查异常,避免强制 try-catch,提升编码体验。

(3) 声明式事务管理(@Transactional):

通过 AOP + 事务管理器(PlatformTransactionManager),开发者无需手动 commit/rollback,只需在方法上加 @Transactional 注解,Spring 就会在方法前后自动开启和提交事务。结合传播行为(Propagation)和隔离级别(Isolation),可灵活应对复杂业务场景。

此外,该层还提供了对主流 ORM 框架的良好集成支持,如 Hibernate、JPA、MyBatis 等,既保留了框架本身的强大功能,又享受 Spring 的事务管理和生命周期管理优势。

至此, 完成了对 Spring 架构的全景扫描 介绍。

从核心容器出发,穿过 AOP、Web、Data 各大功能支线,最终抵达生态顶端的 Boot 与 Cloud。

每一层都不是孤立存在,而是彼此依赖、层层递进的结果

二、Spring 架构的核心设计理念

1. 依赖注入 (Dependency Injection)

在传统开发模式中,对象往往需要自行创建其所依赖的组件,导致类与类之间形成强耦合关系。一旦依赖发生变化(例如更换实现类或添加 mock 测试),就必须修改源码,严重违背了“开闭原则”。这种硬编码式的依赖管理,在项目规模扩大后会显著增加维护成本和测试难度。

而 Spring 框架通过引入依赖注入(DI)机制将对象的创建与依赖的组装过程, 从代码内部剥离出来,交由 IoC 容器统一管理和调度。这样一来,组件之间的协作不再依赖于具体实现,而是基于抽象进行装配,从而实现了真正的松耦合设计。

Spring DI 机制 , 将对象创建和依赖组装的控制权从代码内部转移到外部容器,实现组件间的松耦合。


// 传统方式 - 紧耦合
public class UserService {private UserRepository userRepository = new UserRepositoryImpl();
}// Spring DI - 松耦合
@Component
public class UserService {private final UserRepository userRepository;// 构造器注入public UserService(UserRepository userRepository) {this.userRepository = userRepository;}
}

上面的例子 ,UserService 只需关注“我需要一个用户仓库”,而不必关心“它怎么来、是谁提供的”。

这种职责分离的设计思想,正是现代企业级应用架构的核心理念之一,也是面试中高频考察的“控制反转”与“依赖倒置”原则的实际体现。

2. 面向接口编程

接口作为契约,定义了行为规范,屏蔽了底层实现细节。

Spring 正是依托这一思想,使得同一接口可以有多种实现,并在运行时根据配置或条件动态选择具体实现类。

这不仅提升了系统的灵活性,也为单元测试中的 Mock 替换提供了便利。

以数据访问层为例,我们可以定义一个统一的 UserRepository 接口,约定所有用户查询操作的标准方法:


// 定义接口
public interface UserRepository {User findById(Long id);
}

随后,针对不同的持久化技术,提供各自的实现方案:


@Repository
public class JpaUserRepository implements UserRepository {// JPA 实现,利用 Hibernate 进行 ORM 映射
}@Repository 
public class MybatisUserRepository implements UserRepository {// MyBatis 实现,通过 XML 或注解编写 SQL 映射
}

UserService 通过 DI 注入的是 UserRepository 接口时,Spring 容器会根据当前上下文环境(如配置文件、Profile 设置或 Bean 命名)自动选择合适的实现类完成注入。

开发者无需改动任何业务代码,即可实现数据库访问技术栈的平滑切换。

“面向接口而非实现”的编程方式, 也 是面试官判断候选人是否具备良好设计思维的重要指标 ,往往是拉开差距的关键点。

3. 模板方法模式消除重复代码

在实际开发中,许多通用流程存在大量 通用流程/样板代码(boilerplate code)。

比如 JDBC 操作中的连接获取、预编译语句构建、异常处理、资源释放等。

这些 通用流程/样板代码(boilerplate code), 逻辑高度重复,且与核心业务无关。若每次都手动编写,不仅效率低下,还容易出错。

Spring 大量使用模板方法模式封装通用流程,让开发者 无需关心 通用流程 , 而 专注于业务逻辑 。


// 使用JdbcTemplate前 - 大量重复代码
public User findUser(Long id) {Connection conn = null;PreparedStatement stmt = null;ResultSet rs = null;try {conn = dataSource.getConnection();stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");stmt.setLong(1, id);rs = stmt.executeQuery();// 处理结果集...} finally {// 关闭资源...}
}

这段代码看似简单, 但 几乎每个 DAO 方法都要写一遍 连接获取、预编译语句构建、异常处理、资源释放等,严重影响开发效率和代码整洁度。

而使用 Spring 提供的 JdbcTemplate 后,情况大为改观:

// 使用JdbcTemplate后 - 专注业务逻辑
public User findUser(Long id) {return jdbcTemplate.queryForObject("SELECT * FROM users WHERE id = ?", userRowMapper, id);
}

JdbcTemplate 内部封装了完整的执行流程,开发者只需提供 SQL 和结果映射逻辑(如 RowMapper),其余均由框架自动完成。

短短一行代码 实现业务,JdbcTemplate 完成了 从连接管理、SQL 执行到结果映射的全过程。

这 正是模板方法模式的经典应用。

4. 现代 Spring Boot - 约定优于配置

随着 Spring 功能日益丰富,XML 配置逐渐变得冗长复杂,新手入门门槛高,项目搭建周期长。

为了解决这些问题,Spring 团队推出了 Spring Boot,其核心哲学就是“约定优于配置(Convention over Configuration)”。

这一理念源自 Ruby on Rails,强调通过合理的默认值和自动化机制,减少开发者的手动配置工作。

Spring Boot 的自动配置体系正是这一思想的集中体现。它通过一系列 Starter 依赖、条件化配置和嵌入式容器,构建了一套高度集成的开箱即用解决方案。

Spring Boot 通过"约定优于配置"理念提供开箱即用的自动配置,大幅简化了 Spring 应用的搭建和部署过程。


┌──────────────────────────────────────────────────────────────┐
│                 Spring Boot 自动配置架构                       │
└──────────────────────────────────────────────────────────────┘┌──────────────┐    ┌────────────────┐    ┌───────────────┐│   Starter    │ -> │ 自动配置        │ -> │ 条件化配置      ││  (依赖描述)   │    │ (@EnableAuto   │    │ (@Conditional)│└──────────────┘    │  Configuration)│    └───────────────┘└─────────────────┘△┌───────────────┐    ┌─────────────────┐    ┌─────────────┐│  外部化配置     │ -> │ 嵌入式容器      │ -> │  Actuator   ││ (application  │    │ (Tomcat/Jetty)  │    │ (监控管理)   ││  .properties) │    └─────────────────┘    └─────────────┘└───────────────┘

整个流程可以从左到右拆解为几个关键环节:

  • Starter 依赖:通过引入 spring-boot-starter-web 这样的 starter 包,Maven/Gradle 会自动拉取 Web 开发所需的全部依赖(如 Spring MVC、Jackson、Tomcat),无需逐一声明。
  • 自动配置:Spring Boot 在启动时扫描 classpath,发现存在 DispatcherServlet 类就会自动配置 Spring MVC 环境;发现存在 H2 数据库驱动, 则自动配置内存数据库连接。
  • 条件化配置: 背后是 @Conditional 注解家族的支持,比如 @ConditionalOnClass@ConditionalOnMissingBean,确保配置只在满足特定条件时才生效,避免冲突。
  • 外部化配置:通过 application.propertiesapplication.yml 文件,轻松调整端口、日志级别、数据库地址等参数,支持多环境 Profile 切换。
  • 嵌入式容器:简化部署流程, 不用在 部署 WAR 包到独立 Tomcat。 Spring Boot 内置了 Tomcat、Jetty 等服务器,应用启动即服务,简化部署流程。
  • Actuator 监控:通过 /actuator/health/actuator/metrics 等端点,快速查看应用健康状态、性能指标,便于生产环境运维。

这套机制不仅让初学者能“5 分钟启动一个 REST API”,也让资深开发者能够快速搭建微服务原型、进行敏捷迭代。

三、Spring 中使用的主要设计模式

以下是对 Spring 中 10 种设计模式的逐一解析,包括模式简介、Spring 源码应用、对应的 类图(聚焦核心类关系):

1. 工厂模式(Factory Pattern)

简介:通过工厂类封装对象创建逻辑,用户无需直接实例化对象,降低耦合。

在复杂系统中,如果对象的创建过程散落在各处,不仅会导致代码重复,还会造成模块间的强耦合——一旦构造逻辑变更,多个调用方都得跟着修改。

为了解决这一问题,工厂模式应运而生:它将对象的实例化过程集中到一个“工厂类”中统一管理,使用者只需向工厂提出需求(如传入名称或配置),即可获得对应的实例,而无需关心其背后是如何被创建出来的。

这种设计实现了创建逻辑与使用逻辑的解耦,提升了系统的可维护性和扩展性,是典型的“控制反转”思想的体现。

Spring 源码应用

  • BeanFactory 是核心工厂接口,定义了 getBean() 等方法,负责创建和管理 Bean。
  • ApplicationContext 继承 BeanFactory,扩展了企业级功能(如事件发布、资源加载),是更常用的工厂实现。
  • 核心逻辑:通过 BeanDefinition 解析配置(XML / 注解),由工厂负责实例化、依赖注入。

UML 类图

位于最顶端的是 BeanFactory 接口,它是整个 Bean 创建体系的基石,定义了诸如 getBean()containsBean() 这样的核心方法,构成了 IOC 容器最基本的行为契约。所有具体的工厂实现都必须遵循这一规范。

向下延伸,DefaultListableBeanFactory 实现了 BeanFactory,并成为 Spring 内部真正执行 Bean 创建和注册的核心组件。它内部维护了一个 beanDefinitionMap,用于存储解析后的 BeanDefinition,可以说,它是 Spring 容器的“运行时大脑”。

同时,ApplicationContext 接口也继承自 BeanFactory,但它并不直接参与底层创建细节,而是专注于增强上层能力,比如通过 publishEvent() 支持事件监听模型,或通过 getResource() 提供统一资源访问接口。这体现了典型的“组合优于继承”的设计哲学——在保留基础能力的同时,叠加更高阶的企业特性。

最终,像 AnnotationConfigApplicationContext 这样的具体上下文实现类,则进一步聚焦于特定使用场景,例如基于 Java 注解的配置类启动流程。它在初始化时接收配置类数组,并触发完整的容器刷新流程,包括扫描注解、注册 Bean 定义、创建单例实例等步骤,是开发者日常编码中最常接触的入口点之一。

这个层层递进的类图结构,既体现了面向对象的设计美感,也反映了 Spring 架构中“分层治理、职责分明”的工程智慧。

2. 单例模式(Singleton Pattern)

简介:确保一个类仅存在一个实例,并提供全局访问点。

在大型系统设计中,某些核心组件——比如配置管理器、线程池、缓存容器等——需要在整个应用生命周期中保持唯一性,避免资源浪费或状态冲突。

这就引出了“单例模式”的经典设计意图:保证一个类有且仅有一个实例,并提供一个全局可访问的入口

尤其是在像 Spring 这样的重量级框架中,单例不仅是设计选择,更是性能与一致性的基石。

Spring 源码应用

  • Bean 默认作用域为 singleton,由 SingletonBeanRegistry 接口定义单例管理规范。
  • DefaultSingletonBeanRegistry 实现单例缓存(singletonObjects 哈希表),通过双重检查锁保证线程安全。

UML 类图

位于顶层的是 SingletonBeanRegistry 接口,它定义了获取和注册单例的基本方法,充当整个单例管理体系的契约蓝本。

向下延伸,DefaultSingletonBeanRegistry 作为其实现类,不仅持有了 singletonObjects 这个核心的单例缓存映射表,还引入了 singletonFactories 来处理早期暴露对象和循环依赖问题,展现出更强的扩展能力。

向下延伸,AbstractBeanFactory 继承自 DefaultSingletonBeanRegistry,从而天然具备了对单例 Bean 的管理能力。

当我们调用 getBean() 方法时,实际流程会首先尝试从 singletonObjects 缓存中查找实例——这正是单例模式高效性的体现:“查缓存 → 命中返回 → 未命中则创建并放入缓存”

整个类图清晰地展示了 Spring 如何通过继承与组合的方式,将单例模式无缝集成进 Bean 工厂体系,既保证了架构的清晰分层,又实现了功能的高度复用。

3. 代理模式(Proxy Pattern)

简介:为目标对象创建代理对象,在不修改原对象的情况下增强功能。

在实际开发中,常常需要对某个对象的功能进行增强,比如添加日志、权限校验、事务控制等,但又不希望直接修改原始业务类的代码——这不仅违背了开闭原则,还容易引发耦合和维护难题。

代理模式正是为了解决这一痛点而生:它通过为目标对象创建一个代理对象,在不侵入原逻辑的前提下,实现功能的透明扩展。

这种“中间人”机制,既保持了原有业务的纯粹性,又能灵活地织入横切关注点,是AOP(面向切面编程)的核心实现基础。

Spring 源码应用

  • AOP 底层通过 ProxyFactory 创建代理,支持 JDK 动态代理(JdkDynamicAopProxy)和 CGLIB 代理(CglibAopProxy)。
  • 代理对象会拦截目标方法,执行切面逻辑(如 @Before@After 通知)。

UML 类图

从图中可以看出,AopProxy 作为顶层抽象角色,定义了获取代理对象的统一契约。

JdkDynamicAopProxyCglibAopProxy 分别实现该接口,封装各自特有的代理生成逻辑。

ProxyFactory 则作为客户端与代理系统之间的桥梁,持有目标对象配置,并委托具体的 AopProxy 实现来完成代理创建。

这种职责分离的设计,使得 Spring AOP 具备良好的扩展性和可插拔性,也为我们在面试中解释“AOP底层原理”提供了清晰的思维路径。

4. 模板方法模式(Template Method Pattern)

简介:父类定义算法骨架(固定流程),子类实现具体步骤(可变逻辑)。

在软件设计中,我们常常会遇到这样一类问题:某个操作的执行流程是固定的,比如“连接资源 → 执行操作 → 处理结果 → 释放资源”,但其中某些环节的具体实现却因场景而异。

如果每次都在相同流程中重复编写类似的代码,不仅容易出错,也违背了 DRY 原则。

此时,就需要一种能够“封装不变,扩展可变”的设计模式——模板方法模式应运而生。

它通过在父类中定义完整的算法骨架,将通用流程固化下来,而把需要灵活定制的步骤延迟到子类中实现,从而实现行为的复用与扩展的解耦。

Spring 源码应用

  • JdbcTemplate 封装 JDBC 固定流程(获取连接、处理异常、关闭资源),通过 RowMapper 回调让用户定义结果映射。
  • 核心方法 execute() 为模板,query() 等方法调用模板并传入回调。

UML 类图

JdbcTemplate 并不直接完成所有工作,而是依赖两个关键的回调接口:RowMapperStatementCallback。前者用于定制结果集的映射规则,后者则封装具体的 SQL 执行动作。

虽然严格意义上这更像是“模板方法 + 回调”的混合模式(而非传统继承式的模板方法),但其本质仍体现了模板方法的设计哲学——即控制流程的主导权掌握在模板类手中,外部组件只需聚焦于“变”的部分。

这也解释了为什么 Spring 框架能在保持高度灵活性的同时,依然维持一致的错误处理和资源管理标准。

5. 观察者模式(Observer Pattern)

简介:定义对象间一对多依赖,当 “主题” 状态变化时,通知所有 “观察者”。

在典型的系统设计中,模块之间的耦合如果过高,会导致扩展困难、维护成本上升。

为了解决这一问题,观察者模式应运而生——它是一种行为型设计模式,用于解耦事件的发布者(即“主题”)与订阅者(即“观察者”)。

核心思想是:一个对象(主题)维护一系列依赖它的对象(观察者),一旦状态发生变化,就自动通知所有观察者进行相应处理。这种机制天然适用于需要异步通信或事件驱动的场景。

在 Spring 框架中,这一模式被广泛应用于上下文事件机制,成为实现组件间低耦合通信的重要手段。

Spring 源码应用

  • ApplicationEvent 是事件基类(如 ContextRefreshedEvent)。
  • ApplicationListener 是观察者接口,实现类监听特定事件。
  • ApplicationEventPublisher 负责发布事件,AbstractApplicationContext 实现发布逻辑。

UML 类图

上述类图清晰地描绘了 Spring 事件机制背后的观察者模式结构。

其中,ApplicationEvent 作为所有事件的顶层父类,封装了事件源(source)信息,代表系统中发生的某种状态变更;

ApplicationListener 是参数化接口,通过泛型约束可监听特定类型的事件,并在 onApplicationEvent 方法中执行回调逻辑,体现了“观察者”的行为契约;

ApplicationEventPublisher 定义了事件发布的标准方法,是外部组件触发事件的主要入口。

AbstractApplicationContext 作为整个事件体系的核心协调者,一方面实现了 ApplicationEventPublisher 接口以支持事件发布功能,另一方面持有一组 ApplicationListener 实例,在调用 publishEvent 时逐一通知这些监听器。

箭头关系明确表达了职责流向:上下文向监听器发出通知,监听器则针对具体事件类型做出反应。

这一设计既保证了松耦合,又具备良好的可扩展性,为后续引入异步事件、条件监听等高级特性打下了坚实基础。

6. 适配器模式(Adapter Pattern)

简介:将一个类的接口转换为另一个接口,使不兼容的类可协同工作。

在实际开发中,我们常常会遇到接口不匹配的问题——某些类的设计初衷和当前上下文所需的调用方式存在差异,直接集成会导致耦合度高、扩展性差。

这时,适配器模式(Adapter Pattern)就派上了用场。

它作为一种结构型设计模式,核心作用是“转换接口”,即将一个类的接口封装成客户端所期望的另一种形式,从而让原本因接口不兼容而无法协作的类能够一起工作。

Spring 源码应用

  • HandlerAdapter 适配不同类型的 Handler(如 @RequestMapping 方法、Controller),提供统一的 handle() 方法。
  • RequestMappingHandlerAdapter 专门适配注解式处理器。

UML 类图

图中定义了顶层接口 HandlerAdapter,它规定了所有适配器必须实现的 handle() 方法,作为 DispatcherServlet 与具体处理器之间的统一调用入口。

RequestMappingHandlerAdapter 作为其实现类之一,承担起对接 HandlerMethod 的职责.

HandlerMethod 并不是传统意义上的 Controller 对象,而是一个封装了目标方法(Method)和目标实例(Object)的元数据载体。

注意,RequestMappingHandlerAdapter 并不直接继承或实现 HandlerMethod,而是以依赖关系(association)“适配”它,表明该适配器能够在运行时接收 HandlerMethod 类型的处理器对象,并将其转化为可执行的操作。

这种设计既保持了职责分离,又增强了扩展性:未来若新增其他类型的处理器(如函数式路由、响应式控制器),只需添加新的适配器实现,而不影响现有调用链路。

为了帮助大家理解,尼恩梳理了一下伪代码:


// 适配器接口:定义统一方法
interface HandlerAdapter {ModelAndView handle(request, response, handler);
}// 具体适配器:适配HandlerMethod
class RequestMappingHandlerAdapter implements HandlerAdapter {// 实现统一方法,内部处理HandlerMethodModelAndView handle(request, response, handler) {HandlerMethod hm = (HandlerMethod) handler;// 解析参数、调用目标方法Object result = hm.getMethod().invoke(hm.getBean(), parseParams(request));return new ModelAndView(result);}
}// 前端控制器调用适配器
class DispatcherServlet {void doDispatch() {HandlerMethod handler = handlerMapping.getHandler(request);// 无需关心handler类型,通过适配器调用ModelAndView mav = handlerAdapter.handle(request, response, handler);}
}

整个架构因此具备了高度的模块化与可维护性。 不仅提升了系统的灵活性,也为后续的功能扩展和组件替换提供了良好的解耦基础,特别适用于需要整合遗留系统或第三方库的复杂项目场景。

7. 装饰器模式(Decorator Pattern)

在软件设计中, 常常面临这样一个挑战:如何在不修改原有类代码的前提下,为其动态地增加新的行为或职责?

这就引出了“装饰器模式”的核心思想——通过组合而非继承的方式,在运行时为对象扩展功能。

这种设计既符合开闭原则(对扩展开放、对修改关闭),又能避免因继承导致的类爆炸问题。

经典场景:动态为对象添加额外功能,不改变原类结构。

Spring 源码应用

  • BeanWrapper 包装 Bean 对象,提供属性访问、类型转换等增强功能。
  • BeanWrapperImpl 是主要实现,通过 PropertyAccessor 接口扩展功能。

UML 类图

从设计结构上看,PropertyAccessor 作为顶层接口,定义了属性操作的基本契约——获取与设置属性值,是整个功能体系的入口。

BeanWrapper 在此基础上进一步扩展,引入 getWrappedInstance() 方法,用于暴露被包装的原始对象,从而建立起“包装者-被包装者”的关系模型。

最终,BeanWrapperImpl 作为具体实现类,继承并整合了上述能力,并通过组合方式持有实际的 Object 引用,实现真正的封装与增强。

整个类图清晰地体现了“以接口隔离能力、以继承传递职责、以组合实现复用”的设计哲学。

为了帮助大家理解,尼恩梳理了一下伪代码:


// 顶层接口:定义属性操作契约
interface PropertyAccessor {Object getPropertyValue(String name);void setPropertyValue(String name, Object value);
}// 包装器接口:扩展获取被包装对象能力
interface BeanWrapper extends PropertyAccessor {Object getWrappedInstance();
}// 具体实现:装饰目标对象并增强功能
class BeanWrapperImpl implements BeanWrapper {private Object wrappedObject; // 被装饰的原始对象Object getPropertyValue(String name) {// 注意,在这里可以做增强,比如解析嵌套属性、类型转换等return extractValue(wrappedObject, name); }Object setPropertyValue(String name,String objectvalue) {// 装饰器:带类型检查 + 数据验证// 注意,在这里可以做增强,比如解析嵌套属性、类型转换等return setValue(wrappedObject, name,objectvalue); }Object getWrappedInstance() { return wrappedObject; }}

装饰器模式在 BeanWrapper 中的应用:

// 1. 原始对象
User user = new User("张三", 25);// 2. 创建装饰器包装原始对象
BeanWrapper wrapper = new BeanWrapperImpl(user);// 3. 通过装饰器增强的功能访问属性
wrapper.setPropertyValue("name", "李四");  // 自动类型转换 + 属性验证
Object name = wrapper.getPropertyValue("name");  // 嵌套属性支持// 4. 获取原始对象(装饰器不改变原始对象身份)
User originalUser = wrapper.getWrappedInstance();// 5. 对比:直接访问 vs 装饰器增强访问
user.setName("王五");  // 原始方式:无额外功能
wrapper.setPropertyValue("name", "王五");  // 装饰器:带类型检查 + 数据验证

8. 策略模式(Strategy Pattern)

简介:定义算法家族,封装每个算法,使它们可互换。

在实际开发中,我们经常会遇到一类问题:同一项功能存在多种实现方式,且这些方式在不同场景下可以相互替换。

比如事务管理,既可以基于 JDBC 直接控制,也可以通过 JPA 或 Hibernate 实现;资

比如源加载,既可以从类路径读取,也可以从 Web 上下文中获取。

如果把这些变化的逻辑硬编码到业务代码中,不仅会导致代码臃肿,还会严重降低系统的扩展性和维护性。

此时,就需要一种设计模式来解耦“使用算法”和“实现算法”的关系——这就是策略模式的核心思想。

通过定义一个算法家族,将每一个具体算法封装成独立的类,并让它们实现统一接口,从而实现算法之间的自由切换与动态替换。

Spring 源码应用

  • PlatformTransactionManager 定义事务管理接口,不同实现对应不同策略(如 DataSourceTransactionManager 用于 JDBC 事务)。
  • ResourceLoader 接口的实现(DefaultResourceLoaderServletContextResourceLoader)对应不同资源加载策略。

UML 类图

上述 UML 图直观展示了策略模式在 Spring 事务管理中的结构实现。

PlatformTransactionManager 作为策略接口,扮演着“算法族”的抽象角色,规定了所有事务管理器必须遵循的行为契约。

DataSourceTransactionManagerJpaTransactionManager 则是具体的策略实现类,各自封装了针对不同持久化技术的事务控制逻辑。

客户端(如 TransactionTemplate 或声明式事务代理)仅依赖于顶层接口,运行时根据配置动态注入具体实现,从而实现策略的透明切换。

这种设计不仅符合开闭原则(对扩展开放,对修改关闭),还为单元测试中的 mock 替换提供了便利,是面试中高频考察的“设计模式 + 源码实践”结合点。

9. 责任链模式(Chain of Responsibility Pattern)

简介:多个处理器按顺序处理请求,每个处理器可决定是否传递给下一个。

核心思想是将请求的处理过程分解为多个独立的处理单元(即“处理器”),这些处理器按照预定义的顺序串联成一条链。

当请求进入链时,会依次经过每个处理器进行判断和操作——而关键在于,每一个处理器都有权决定是否继续将请求传递给下一个节点。

如果当前处理器能够独立完成处理或判定请求不合法,则可以直接中断流程,无需后续执行。

这种设计不仅实现了请求发送者与接收者之间的解耦,还提升了系统的灵活性和扩展性,特别适用于需要多级校验、过滤或增强逻辑的场景。

Spring 源码应用

  • HandlerInterceptor 构成拦截器链,preHandle()postHandle() 等方法按顺序执行。
  • HandlerExecutionChain 管理拦截器列表,负责链式调用。

UML 类图

HandlerInterceptor 作为所有拦截器的统一接口,定义了 preHandlepostHandleafterCompletion 三大核心方法,为各类业务定制提供了标准契约。

具体的拦截逻辑则由其实现类如 LoginInterceptor 来完成,例如在 preHandle 中验证用户登录状态并决定是否放行请求。

HandlerExecutionChain 扮演了“责任链管理者”的角色,内部持有一个 List<HandlerInterceptor>,负责按序调度各个拦截器的方法调用。

它提供的 applyPreHandleapplyPostHandle 等方法封装了链式传播的控制逻辑,比如一旦某个 preHandle 返回 false,就会停止遍历并直接返回失败信号。这种职责分离的设计使得链的构建与执行逻辑高度内聚,同时也便于测试和扩展——新增一个拦截器无需修改原有代码,只需注册即可生效,完美契合开闭原则。

10. 外观模式(Facade Pattern)

外观模式(Facade Pattern) 简介:为子系统中的一组接口提供一个统一的高层接口,使子系统更易于使用。

在实际开发中,我们常常会遇到这样的场景:多个复杂的子系统协同工作才能完成某个功能,而外部调用者无需关心子系统的内部细节,只需要一个简单的入口即可触发整个流程。

这种设计的核心思想正是外观模式(Facade Pattern)。它强调接口简化 —— 外观对象封装子系统的交互逻辑,为外部提供统一的调用入口,屏蔽内部复杂的协作细节。

这种方式不仅降低了外部与子系统的耦合度,也减少了调用者的使用成本,让复杂系统的调用变得简单直观。

因此,外观模式作为经典的 23 种 GoF 设计模式之一,在框架设计中常用于封装内部复杂性,提供友好的对外接口。

Spring 源码应用

  • DispatcherServlet 作为前端控制器,封装了 HandlerMapping 查找处理器、HandlerAdapter 执行方法等一系列子系统交互,为外部请求提供统一的入口,调用者无需关心内部组件的协作细节。

UML 类图

从类图可以看出,DispatcherServletHandlerMappingHandlerAdapter 之间是典型的封装关系,且这种关系完全服务于 “简化接口” 这一目的。

外部只需通过 DispatcherServlet 即可触发完整流程:

doDispatch() 方法作为整个请求处理的统一入口,内部封装了调用 getHandler() 获取处理器、通过 handle() 执行方法等一系列子系统交互逻辑。

这种高内聚的封装方式,使得外部调用者无需了解子系统的存在:比如新增或替换 HandlerAdapter 时,外部调用方式无需任何改变,只需保证与 DispatcherServlet 的交互契约不变。

这也印证了 “封装复杂性,暴露简单性” 的设计原则,为框架的易用性和稳定性提供了坚实支撑。

11. 委派模式(Delegate Pattern)

上面的图中,还用到 委派模式(Delegate Pattern)。

委派模式(Delegate Pattern)简介:一个对象将任务委派给其他对象执行,自身仅负责协调。

在实际开发中,我们常常会遇到这样的场景:某个核心组件并不直接参与具体业务逻辑的实现,而是扮演“指挥官”的角色,根据上下文环境将具体工作分发给合适的协作对象去完成。

这种设计的核心思想正是委派模式(Delegate Pattern)。它强调职责分离——主控对象专注于流程调度与协调,而将具体的处理逻辑交给专门的处理器来执行。

这种方式不仅提升了代码的模块化程度,也为后续的功能扩展和维护提供了良好的结构基础。

因此,委派模式虽未被列为经典的23种GoF设计模式之一,但在大型框架和复杂系统中却无处不在。

Spring 源码应用

  • DispatcherServlet 作为主控对象(前端控制器),将请求委派给 HandlerMapping 查找处理器、HandlerAdapter 执行方法等,自身不处理业务。

UML 类图

从类图可以看出,DispatcherServletHandlerMappingHandlerAdapter 之间是典型的依赖关系,且这种依赖完全服务于“任务委派”这一目的。

doDispatch() 方法作为整个请求分发的核心入口,内部通过调用 getHandler() 动态获取处理器,再交由 handle() 方法完成实际执行。

这种松耦合的交互方式,使得各个组件可以独立演化:比如新增一种自定义的 HandlerAdapter 支持新的控制器类型时,只需注册即可生效,DispatcherServlet 本身无需任何改动。

这也印证了“针对接口编程,而非实现”的设计原则,为框架的可插拔架构提供了坚实支撑。

spring 设计 小结

Spring 大量运用设计模式解决实际问题:工厂模式管理 Bean 生命周期,代理模式支撑 AOP,策略模式实现多方案灵活切换等。

这些模式的组合使 Spring 具备高扩展性和低耦合的特性,也是框架设计的经典范例。

四、一条 Rest微服务 请求走过的“设计模式链路”

......... 略5000字+

...................由于平台篇幅限制, 剩下的内容(5000字+),请参参见原文地址

原始的内容,请参考 本文 的 原文 地址

本文 的 原文 地址

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

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

相关文章

实用指南:《中国电力产业数字化》深度解析与前沿展望(下)——中国电力数字化转型路线图:SPARK 融合平台的设计与落地方案

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

High Frequency Active Auroral Research Program(HAARP)部分摘取

High Frequency Active Auroral Research Program(HAARP)部分摘取原网站:https://haarp.gi.alaska.edu/ 部分摘取:利用最近研发的强大且灵活的电离层加热器(如EISCAT加热器,以及最近建成的HAARP加热器)对高频无…

CF813E Army Creation

考虑套用 HH 的项链做法,如果一个数前面第 \(k\) 个数小于 \(l\) 则可以选,那么用主席树维护值域线段树即可。

Mac 怎么安装 PyCharm 2020.1.dmg?超简单教程(附安装包)

Mac 怎么安装 PyCharm 2020.1.dmg?超简单教程(附安装包)​ 一、下载文件 安装包下载:https://pan.quark.cn/s/c35137bf43ce , PyCharm 2020.1.dmg文件,一般是在浏览器下载后,放在了「下载」文件夹里。如果没有,…

C# 蓝牙远程控制应用:从零达成移动设备与硬件的无线交互

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

铭记旧友

命运,总是一个恶劣地笑着,将人间搅得天翻地覆的死神。这次祂将手伸向她的父母,以名为“期许”的毒药杀死了她。 也曾挣扎过,将呼救之声传入爱情之耳,却不知会陷入更深的泥泞。 缺爱吗?或许吧,但命运所施舍给她的…

标题:鸿蒙Next音频开发新篇章:深入解析Audio Kit(音频服务) - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Spring AI Alibaba 项目源码学习(十二)-完结:Tool

Tool 系统分析 请关注微信公众号:阿呆-bot 概述 本文档分析 Spring AI Alibaba Agent Framework 中的 Tool(工具)系统,包括工具的定义、注册、调用流程、扩展机制以及 AgentTool 的实现。 入口类说明 ToolCallback…

ftp,sftp,scp,tftp几种简单对比,以及python实现ftp功能

ftp,sftp,scp,tftp几种简单对比,以及python实现ftp功能对比如下:特性维度FTPSFTPSCPTFTP安全性 明文传输 基于SSH加密 基于SSH加密 无加密默认端口 21 22 22 69协议基础 TCP SSH SSH UDP认证方式 用户名/密码 多种(…

实用指南:深入解析音频编解码器(Audio CODEC):硬件、接口与驱动开发

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

福利MegaLLM–175刀免费额度建教程

0.简介 MegaLLM 是一个 API 中转服务,支持主流模型 OpenAI、Anthropic、Google、Meta 等,以及包括国产千问、DeepSeek、GLM、K2 等。可以在 Claude Code、 Codex、OpenCode、Kilocode、RooCode... 1. 注册就送 75 刀…

C# 常用控件(学习笔记8)

1. TreeView 树形控件/// <summary> /// 添加 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnTreeAdd_…

模拟赛记录 11/18

显然不应该把别人的模拟赛指认成自己的。

代码随想录Day14_

代码随想录Day14_226. 翻转二叉树 - 力扣(LeetCode)class Solution { public:TreeNode* invertTree(TreeNode* root) {if(root==NULL) return root;swap(root->left,root->right);invertTree(root->left);i…

白嫖MegaLLM–175刀免费额度建教程

0.简介 MegaLLM 是一个 API 中转服务,支持主流模型 OpenAI、Anthropic、Google、Meta 等,以及包括国产千问、DeepSeek、GLM、K2 等。可以在 Claude Code、 Codex、OpenCode、Kilocode、RooCode... 1. 注册就送 75 刀…

如何找到适合好用的 AI 数据分析工具?Aloudata Agent 值得一试!

AI 数据分析软件则通过自然语言交互、智能问数、自动化建模查询等技术,让业务人员无需写复杂的 SQL 即可自主获取数据洞察,快速定位问题根因,并生成结构化决策建议。AI 数据分析软件显著提升企业决策精准性与敏捷性…

linux burpsuite

Burp Suite 是一个用于 Web 应用程序安全测试的工具,主要用于拦截和修改 HTTP 请求/响应,进行安全测试,如漏洞扫描、渗透测试等。它不是 Linux 系统的一部分,而是独立的软件,通常通过下载安装包进行部署。 如果你…

linux bug

您提到的“Linux bug”可能是指Linux系统中出现的bug或问题。Linux是一个开源操作系统,其稳定性、性能和安全性在社区的持续维护下不断提升。如果您遇到Linux系统中的问题,比如崩溃、性能下降、功能异常等,可以具体…

linux broadcom

您提到的 + #引号 + Linux Broadcom + #引号 + 可能是指与 Broadcom 公司相关的 Linux 系统或驱动,特别是在网络设备、无线网卡(如 RTL8812AE、RTL8814AE 等)的驱动支持方面。一、Broadcom 无线网卡驱动支持 …

Duan.ai - 将长视频变成适合社交的短视频AI工具

将长视频变成适合社交的短视频AI工具 现在的视频平台越来越“快节奏”。 抖音、快手、小红书、B站、YouTube Shorts…… 用户只愿意给内容 3 秒钟的耐心。 可现实是:我们手里大量素材都是 几分钟甚至几十分钟的长视频…