Spring核心设计模式

Spring 框架之所以成为 Java 生态事实标准,核心并非单纯封装 API,而是通过合理、克制、精准的设计模式解决了原生 Java 开发的各类工程痛点。

一、单例模式(Singleton)

1. Spring 落地场景

Spring IOC 容器中 默认 Bean 作用域为单例(singleton)。整个容器中同一个 Bean 仅实例化一次,全局复用单例对象。

注意:Spring 并非使用原生饿汉/懒汉单例,而是容器级可控单例,由 IOC 统一管理创建、销毁、依赖注入。

2. 为什么需要该模式

原生开发中,业务 Bean、工具类反复 new 对象,会造成大量内存对象冗余、频繁 GC、资源浪费。

无单例管控时,每层业务都自主 new 对象,对象不可控、无法统一初始化、无法统一销毁。

3. 使用后的核心优点

  • 极致节省内存:全局唯一实例,避免重复创建大量无用对象,降低内存占用与 GC 压力。

  • 统一资源管控:容器统一初始化、依赖注入、销毁回调,对象生命周期完全可控。

  • 提升系统性能:无需反复执行构造方法、初始化逻辑,大幅提升接口响应速度。

4. 工程取舍与避坑

单例 Bean 非线程安全,禁止在 Bean 中定义成员变量存储业务状态,避免并发脏数据。有状态场景必须使用 prototype 多例。

二、工厂模式(Factory)

1. Spring 落地场景

Spring 核心两大工厂:BeanFactory 、ApplicationContext。

所有 Bean 对象不通过开发者 new 创建,全部由工厂统一生产、组装、管理。同时 Spring 各类资源、解析器、策略类均由工厂统一获取。

2. 为什么需要该模式

传统开发 硬编码 new 对象,对象创建与业务代码强耦合。

如果业务层直接 new Dao、new Service,后续替换实现类、修改初始化逻辑需要改动所有业务代码,扩展性极差。

3. 使用后的核心优点

  • 彻底解耦创建与使用:业务层只负责调用,不负责对象创建,符合单一职责。

  • 统一生产规范:所有 Bean 统一经过实例化、属性填充、初始化、后置处理,流程标准化。

  • 极高扩展性:替换底层实现无需改业务代码,只改容器配置。

三、单例工厂配套:注册器模式(Registry)

1. Spring 落地场景

BeanDefinitionRegistry、Bean 注册表、处理器注册表、拦截器注册表。

Spring 启动时扫描所有 Bean,统一注册到注册表,工厂根据注册表信息实例化对象。

2. 为什么需要该模式

工厂需要「生产依据」,如果没有注册表,工厂无法知道需要创建哪些 Bean、Bean 的属性与依赖是什么。

3. 核心优点

实现 配置与生产分离,先批量注册定义,再统一实例化,支撑 Spring 全自动 IOC 能力。

四、代理模式(Proxy)

1. Spring 落地场景

AOP 核心底层、事务注解 @Transactional、权限拦截、日志切面、缓存切面全部基于动态代理实现。

Spring 自动适配:有接口用 JDK 动态代理,无接口用 CGLIB 代理。

2. 为什么需要该模式

原生开发中,日志、事务、权限、监控属于通用横切逻辑。

如果直接写在业务方法内,会导致业务代码充斥非业务冗余逻辑,代码臃肿、无法复用、修改成本极高。

3. 使用后的核心优点

  • 业务与非业务逻辑解耦:核心业务只写业务逻辑,事务、日志、监控全部抽离切面。

  • 无侵入增强:不修改目标方法源码,即可对方法做功能增强,符合开闭原则。

  • 统一管控:所有横切逻辑统一收口,统一规则、统一维护、统一迭代。

五、装饰器模式(Decorator)

1. Spring 落地场景

BeanPostProcessor、BeanFactoryPostProcessor、各类后置增强处理器。

Spring 创建完原生 Bean 后,通过多层后置处理器对 Bean 层层装饰、增强、修改属性、生成代理对象。

2. 为什么需要该模式

Bean 原生创建逻辑固定,无法灵活扩展。如果新增功能就要改创建源码,框架完全无法迭代。

装饰器模式允许 在不修改原有代码的前提下,层层叠加增强能力。

3. 核心优点

  • 多层增强互不干扰,可单独开启、关闭、替换处理器。

  • 支撑 Spring 极高的扩展性,各类中间件、插件均通过后置处理器扩展。

  • 遵循开闭原则,原生代码稳定不变,能力无限扩展。

六、适配器模式(Adapter)

1. Spring 落地场景

HandlerAdapter 处理器适配器、各种类型参数解析器、返回值处理器。

Spring MVC 中 Controller 方法参数、返回值类型五花八门,通过适配器统一适配、统一调用。

2. 为什么需要该模式

如果没有适配器,DispatcherServlet 需要写无数 if/else 判断不同方法类型,代码极度臃肿、无法扩展。

3. 核心优点

  • 统一调用入口,适配多种异构接口。

  • 新增方法类型、参数类型无需改动核心源码,只新增适配器。

  • 彻底消除臃肿分支判断代码。

七、策略模式(Strategy)

1. Spring 落地场景

资源加载策略、类型转换策略、代理策略、解析策略、校验策略。

典型场景:根据不同环境、不同类型自动选用不同执行策略。比如:有接口用 JDK 代理、无接口用 CGLIB 代理。

2. 为什么需要该模式

多分支业务如果用 if/else 硬编码,逻辑混乱、新增策略需要改核心代码、可读性极差。

3. 核心优点

  • 分支逻辑独立封装,每种策略单独一个类。

  • 策略可自由切换、可动态替换。

  • 彻底消灭 if/else,代码整洁易维护。

八、模板方法模式(Template Method)

1. Spring 落地场景

Spring 大量模板类:JdbcTemplate、RedisTemplate、TransactionTemplate。

父类固定整体执行流程、事务流程、资源开关流程,开放抽象方法给子类自定义实现。

2. 为什么需要该模式

数据库连接、关闭、事务开启、提交、回滚、资源释放是固定通用流程。

如果每个开发者自己写连接、关闭、事务,极易出现资源泄漏、事务不规范、重复代码泛滥。

3. 核心优点

  • 固定骨架,开放扩展:通用流程框架统一管控,业务只需关注自定义逻辑。

  • 杜绝资源泄漏、事务错乱,统一编码规范。

  • 极大减少重复模板代码,开发效率翻倍。

九、观察者模式(Observer)

1. Spring 落地场景

Spring 事件机制:ApplicationEvent、ApplicationListener、事件发布与监听。

容器刷新完成事件、Bean 加载完成事件、自定义业务事件全部基于观察者模式。

2. 为什么需要该模式

业务之间存在大量联动操作,如果采用硬编码调用,业务强耦合、改动一处牵连多处。

例如:用户注册成功后发积分、发短信、发日志,硬编码会导致注册方法极度臃肿。

3. 核心优点

  • 发布订阅解耦:发布方只管发布事件,无需关心谁监听、如何处理。

  • 新增业务联动无需改原有代码,新增监听类即可。

  • 业务联动清晰、可扩展、可降级。

十、Spring 设计模式全局总结

Spring 所有设计模式的核心目的只有三件事:解耦、统一管控、高可扩展。

  • 工厂 + 单例 + 注册器:解决对象创建混乱、资源浪费问题,实现 IOC 容器核心能力。

  • 代理 + 装饰器:解决通用横切逻辑冗余问题,实现 AOP 无侵入增强。

  • 适配器 + 策略:解决多类型适配、多分支臃肿问题,提升框架兼容性。

  • 模板方法:解决通用流程不统一、资源泄漏问题,标准化开发范式。

  • 观察者:解决业务联动耦合问题,实现事件驱动、业务解耦。

相关推荐
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时3 天前
01-06-A-JVM排查实战详解
java·jvm
vipxieliang3 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
ba_pi3 天前
mysql 查询所有表名并授权
java
ProcessOn官方账号3 天前
java函数式编程--入门基础
java·编程·函数式编程