首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >聊聊Spring中最常用的10种设计模式

聊聊Spring中最常用的10种设计模式

作者头像
苏三说技术
发布于 2025-06-16 03:47:48
发布于 2025-06-16 03:47:48
25800
代码可运行
举报
文章被收录于专栏:苏三说技术苏三说技术
运行总次数:0
代码可运行

苏三的宝藏网站(面试题、简历模版、项目实战什么都有):http://www.susan.net.cn

大家好,我是苏三,又跟大家见面。

前言

作为一名有多年开发经验的老司机,每次看Spring源码都让我感叹:"这哪是框架,分明是设计模式的百科全书!"

有些小伙伴在工作中可能只会用@Autowired,却不知背后藏着多少精妙设计。

今天这篇文章跟大家一起聊聊Spring中最常用的10种设计模式,希望对你会有所帮助。

1 模板方法模式:流程骨架大师

场景:处理重复流程但允许细节变化 Spring应用JdbcTemplateRestTemplate

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 伪代码展示模板方法核心
publicabstractclass JdbcTemplate {
    // 定义算法骨架(不可重写)
    public final Object execute(String sql) {
        Connection conn = getConnection(); // 抽象方法
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        Object result = mapResult(rs);     // 抽象方法
        releaseResources(conn, stmt, rs);
        return result;
    }
    
    // 留给子类实现的钩子方法
    protected abstract Connection getConnection();
    protected abstract Object mapResult(ResultSet rs);
}

为什么用

  1. 复用资源管理(连接获取/释放)等通用逻辑
  2. 允许子类只关注业务差异(如结果映射) 思考:当你写重复流程时,想想能否抽出模板骨架

2 工厂模式:对象出生管理局

场景:解耦对象创建与使用 Spring应用BeanFactory核心接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface BeanFactory {
    Object getBean(String name);
    <T> T getBean(Class<T> requiredType);
}

// 实现类:DefaultListableBeanFactory
public class UserService {
    // 使用者无需关心Bean如何创建
    @Autowired 
    private OrderService orderService; 
}

设计精髓

  • 隐藏复杂的对象初始化过程(如循环依赖处理)
  • 统一管理对象生命周期(单例/原型等作用域) 类比:就像点外卖不需要知道厨师怎么做菜

3 代理模式:隐形护卫

场景:无侵入增强对象功能

Spring应用:AOP动态代理

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// JDK动态代理示例
publicclass LogProxy implements InvocationHandler {
    private Object target;
    
    public Object createProxy(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            this);
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        System.out.println("【日志】调用方法: " + method.getName());
        return method.invoke(target, args); // 执行原方法
    }
}

// Spring中通过@Aspect实现类似功能
@Aspect
@Component
publicclass LogAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void logMethodCall(JoinPoint jp) {
        System.out.println("调用方法: " + jp.getSignature().getName());
    }
}

动态代理两板斧

  1. JDK代理:基于接口(要求目标类实现接口)
  2. CGLIB代理:基于继承(可代理普通类) 价值:业务逻辑与横切关注点(日志/事务等)彻底解耦

4 单例模式:全局唯一指挥官

场景:减少资源消耗,保证全局一致性

Spring实现:Bean默认作用域

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 源码片段:AbstractBeanFactory
public Object getBean(String name) {
    Object bean = getSingleton(name); // 先查缓存
    if (bean == null) {
        bean = createBean(name);      // 不存在则创建
        addSingleton(name, bean);     // 放入缓存
    }
    return bean;
}

关键设计

  • 三级缓存解决循环依赖(singletonObjects, earlySingletonObjects, singletonFactories)
  • 并发安全通过synchronized+双重检查锁定实现 警示:切忌在单例Bean中保存状态变量!

5 观察者模式:事件广播网

场景:解耦事件生产者和消费者

Spring应用ApplicationEvent机制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 1. 定义事件
publicclass OrderCreatedEvent extends ApplicationEvent {
    public OrderCreatedEvent(Order source) {
        super(source);
    }
}

// 2. 发布事件
@Service
publicclass OrderService {
    @Autowired ApplicationEventPublisher publisher;
    
    public void createOrder(Order order) {
        // 业务逻辑...
        publisher.publishEvent(new OrderCreatedEvent(order));
    }
}

// 3. 监听事件
@Component
publicclass EmailListener {
    @EventListener
    public void handleOrderEvent(OrderCreatedEvent event) {
        // 发送邮件通知
    }
}

优势

  • 事件源与监听器完全解耦
  • 支持异步处理(加@Async注解即可)

6 策略模式:算法切换器

场景:动态选择算法实现

Spring应用Resource资源加载

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 资源加载策略族
Resource res1 = new ClassPathResource("config.xml"); // 类路径策略
Resource res2 = new UrlResource("http://config.com");// 网络策略
Resource res3 = new FileSystemResource("/opt/config");// 文件系统策略

// 统一调用接口
InputStream is = res1.getInputStream();

源码设计亮点

  • Resource接口统一抽象
  • 通过ResourceLoader自动选择策略 应用场景:支付方式切换(微信/支付宝/银联)

7 适配器模式:接口转换器

场景:兼容不兼容的接口

Spring应用:Spring MVC的HandlerAdapter

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 伪代码:处理多种Controller
publicclass RequestMappingHandlerAdapter implements HandlerAdapter {
    
    public boolean supports(Object handler) {
        return handler instanceof Controller;
    }
    
    public ModelAndView handle(HttpRequest req, HttpResponse res, Object handler) {
        Controller controller = (Controller) handler;
        return controller.handleRequest(req, res); // 统一适配调用
    }
}

// 实际Spring源码中处理了:
// 1. @Controller注解类 2. HttpRequestHandler 3. Servlet实现等

价值

  • 让DispatcherServlet无需关心Controller具体类型
  • 新增Controller类型只需扩展适配器

8 装饰器模式:功能增强包

场景:动态添加功能

Spring应用HttpServletRequest包装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 典型应用:缓存请求体
ContentCachingRequestWrapper wrappedRequest = 
    new ContentCachingRequestWrapper(rawRequest);

// 可在filter中多次读取body
byte[] body = wrappedRequest.getContentAsByteArray();

源码实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ContentCachingRequestWrapper extends HttpServletRequestWrapper {
    private ByteArrayOutputStream cachedContent;
    
    @Override
    public ServletInputStream getInputStream() {
        // 装饰原方法:缓存流数据
    }
}

设计本质:通过包装器在不修改原对象基础上增强功能

9 建造者模式:复杂对象组装工

场景:分步构建复杂对象

Spring应用BeanDefinitionBuilder

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 构建复杂的Bean定义
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(UserService.class);
builder.addPropertyValue("maxRetry", );
builder.setInitMethodName("init");
builder.setScope(BeanDefinition.SCOPE_SINGLETON);

// 注册到容器
registry.registerBeanDefinition("userService", builder.getBeanDefinition());

对比传统构造

  • 解决多参数构造的混乱(尤其可选参数多时)
  • 构建过程更加清晰可读

十、责任链模式:拦截器的骨架

MVC拦截器实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 伪代码:拦截器链执行
publicclass HandlerExecutionChain {
    privatefinal List<HandlerInterceptor> interceptors = new ArrayList<>();
    
    boolean applyPreHandle(HttpRequest req, HttpResponse res) {
        for (HandlerInterceptor interceptor : interceptors) {
            if (!interceptor.preHandle(req, res)) returnfalse; // 中断链
        }
        returntrue;
    }
}

// 自定义拦截器
publicclass LogInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res) {
        System.out.println("请求进入: " + req.getRequestURI());
        returntrue; // 继续执行
    }
}

10 责任链模式:拦截器的骨架设计

场景:解耦多步骤处理流程

Spring应用HandlerInterceptor拦截器链

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Spring MVC核心执行链
publicclass HandlerExecutionChain {
    privatefinal List<HandlerInterceptor> interceptors = new ArrayList<>();
    
    // 执行前置处理(责任链核心)
    public boolean applyPreHandle(HttpServletRequest request, 
                                 HttpServletResponse response) {
        for (int i = ; i < interceptors.size(); i++) {
            HandlerInterceptor interceptor = interceptors.get(i);
            // 任意拦截器返回false则中断链条
            if (!interceptor.preHandle(request, response, this.handler)) {
                triggerAfterCompletion(request, response, i); // 清理已完成
                returnfalse;
            }
        }
        returntrue;
    }
}

实战配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
publicclass WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 构建责任链
        registry.addInterceptor(new LogInterceptor()).order();
        registry.addInterceptor(new AuthInterceptor()).order();
        registry.addInterceptor(new RateLimitInterceptor()).order();
    }
}

// 独立拦截器实现
publicclass AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
        if (!checkToken(req.getHeader("Authorization"))) {
            res.sendError(); // 认证失败
            returnfalse; // 中断链
        }
        returntrue; // 放行
    }
}

设计价值

  1. 开闭原则:新增拦截器无需修改现有代码
  2. 单一职责:每个拦截器只关注单一功能
  3. 动态编排:通过order()灵活调整执行顺序
  4. 流程控制:任意节点可中断或继续传递

典型反模式:在拦截器中注入其他拦截器,这将破坏责任链独立性,导致循环依赖!

总结

  1. 解耦的艺术 工厂模式解耦创建/使用,观察者模式解耦事件/处理
  2. 扩展性的智慧 策略模式支持算法扩展,装饰器模式支持功能扩展
  3. 复杂性的封装 模板方法封装流程,建造者模式封装构建
  4. 性能的权衡 单例模式减少资源消耗,代理模式按需增强

最后送给小伙伴们的建议:不要为了用模式而用模式

就像Spring的作者Rod Johnson说的:"优雅的代码不是模式的堆砌,而是恰到好处的抽象。"

当你下次写代码感到别扭时,不妨想想这些经典模式,或许能豁然开朗。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
最后欢迎加入苏三的星球,你将获得:商城微服务实战、AI开发项目课程、苏三AI项目、秒杀系统实战、商城系统实战、秒杀系统实战、代码生成工具、系统设计、性能优化、技术选型、底层原理、Spring源码解读、工作经验分享、痛点问题、面试八股文等多个优质专栏。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 苏三说技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
不讲废话,全程干货,0基础带你学习SpringMVC拦截处理器
类似Servlet的过滤器Filter,对处理器进行预处理、后处理。HandlerInterceptor接口方法:
JavaEdge
2021/12/07
2570
不讲废话,全程干货,0基础带你学习SpringMVC拦截处理器
Spring 全家桶之 Spring Web MVC(七)- Interceptor
Spring MVC提供了拦截器机制,允许在运行目标方法前进行一些拦截工作,或者在目标方法运行之后进行一些其他处理
RiemannHypothesis
2022/08/19
5270
Spring 全家桶之 Spring Web MVC(七)-  Interceptor
设计模式之责任链模式
本文通过图书馆管理系统中,用户名校验、密码校验、需要增加问题,每次都要增加if判断语句,将其改用责任链模式进行链式调用,为了让代码更加的优雅,我们使用之前学过的建造者模式就代码进行改造。接着我们会介绍责任链模式在我们常用的框架中的运用,最后是责任链模式的优缺点和应用场景。
程序员田同学
2022/08/24
3630
设计模式之责任链模式
谈谈springboot的责任链模式
责任链模式是一种行为设计模式,旨在将请求的发送者和接收者解耦。在这种模式中,多个对象可以处理同一请求,但具体由哪个对象处理,则取决于运行时决定。这样的设计使得请求的处理者形成一条链,每个处理者都有机会处理请求或者将其传递给链中的下一个处理者。
小马哥学JAVA
2024/04/20
8850
【愚公系列】2023年04月 Java教学课程 140-Spring MVC框架的拦截器
---- 一、拦截器 1.拦截器概念 请求处理过程解析 拦截器( Interceptor)是一种动态拦截方法调用的机制 作用: 在指定的方法调用前后执行预先设定后的的代码 阻止原始方法的执行 核心原理: AOP思想 拦截器链:多个拦截器按照一定的顺序,对原始被调用功能进行增强 拦截器VS过滤器 归属不同: Filter属于Servlet技术, Interceptor属于SpringMVC技术 拦截内容不同: Filter对所有访问进行增强, Interceptor仅针对
愚公搬代码
2023/04/21
1580
【愚公系列】2023年04月 Java教学课程 140-Spring MVC框架的拦截器
过滤器和拦截器的 6 个区别,别再傻傻分不清了
毕竟这两种工具开发中用到的频率都相当高,应用起来也是比较简单的,可当我准备回复他的时候,竟然不知道从哪说起,支支吾吾了半天,场面炒鸡尴尬有木有,工作这么久一个基础问题答成这样,丢了大人了。
后端码匠
2020/06/09
3.2K0
过滤器和拦截器的 6 个区别,别再傻傻分不清了
聊一聊责任链模式
责任链模式(Chain of Responsibility Pattern)是将链中每一个节点看作是一个对象,每个节点处理的请求均不同,且内部自动维护一个下一节点对象。当一个请求从链式的首端发出时,会沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,属于行为型模式。下面放一张足球比赛的图,通过层层传递,最终射门。通过这张图,可以更好的理解责任链模式。
知了一笑
2022/11/30
3710
聊一聊责任链模式
Spring学习笔记(8)--拦截器Interceptor和过滤器Filter的区别详解
过滤器和拦截器 底层实现方式大不相同:过滤器是基于函数回调的,拦截器则是基于Java的反射机制(动态代理)实现的。
黄规速
2022/04/14
5.1K0
Spring学习笔记(8)--拦截器Interceptor和过滤器Filter的区别详解
【二十二】springboot整合拦截器实战并对比过滤器
本章和上章相比,通过使用拦截器的方式去模拟处理token的校验,再之后通过两者的对比,比较一下两者的不同。下面开始拦截器的基础用法学习。
小z666
2024/06/21
4510
【二十二】springboot整合拦截器实战并对比过滤器
使用springmvc的拦截器应用
Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理。
sunonzj
2022/06/21
4390
使用springmvc的拦截器应用
Spring 详解(三)------- SpringMVC拦截器使用
在实际应用中,咱们一般都是通过实现 HandlerInterceptor 接口或者继承 HandlerInterceptorAdapter 抽象类,复写 preHandle()、postHandle() 和 afterCompletion()这 3 个方法来对用户的请求进行拦截处理的。
海向
2019/09/23
5990
SpringBoot中的拦截器江湖
很多小伙伴在工作中遇到拦截需求就无脑写HandlerInterceptor,结果被复杂场景搞得鼻青脸肿。
苏三说技术
2025/05/09
1590
SpringBoot中的拦截器江湖
Java描述设计模式(15):责任链模式
这里分析的几个方法,都是从DispatcherServlet类的doDispatch方法中请求的。
知了一笑
2019/10/23
4310
Java描述设计模式(15):责任链模式
一文读懂Spring MVC执行流程
说到Spring MVC执行流程,网上有很多这方面的文章介绍,但是都不太详细,作为一个初学者去读会有许多不理解的地方,今天这篇文章记录一下我学习Spring MVC的心得体会
说故事的五公子
2019/10/24
1.7K0
Spring Web MVC 拦截器
  Spring Web MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(InterceptorChain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是 AOP思想的具体实现。
Demo_Null
2020/09/28
6690
Spring Web MVC 拦截器
SpringMVC 的处理拦截器0 目录1 Spring MVC拦截器流程图2 Spring Web MVC 的处理器拦截器3 拦截器配置4 拦截器Handler
0 目录 1 Spring MVC拦截器流程图 2 Spring Web MVC 的处理器拦截器 类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理 HandlerInt
JavaEdge
2018/05/16
8000
Spring MVC核心技术
目录 异常处理 类型转换器 数据验证 文件上传与下载 拦截器 ----  异常处理 Spring MVC中, 系统的DAO, Service, Controller层出现异常, 均通过throw Ex
用户1216491
2018/03/29
9400
Spring MVC核心技术
深入理解 Spring 中的各种注解,总有一款是你需要的!
spring的bean容器相关的注解,先后有:@Required, @Autowired, @PostConstruct, @PreDestory
Java小咖秀
2021/04/20
5440
深入理解 Spring 中的各种注解,总有一款是你需要的!
【小家Spring】Spring MVC容器的web九大组件之---HandlerMapping源码详解(一)---BeanNameUrlHandlerMapping系列
在这篇文章里: 【小家Spring】Spring MVC容器启动时,web九大组件初始化详解(Spring MVC的运行机制) 已经大概介绍过web九大组件,本文将聚焦于Spring MVC中最重要的一个组件:HandlerMapping展开讨论
YourBatman
2019/09/03
1.4K0
【小家Spring】Spring MVC容器的web九大组件之---HandlerMapping源码详解(一)---BeanNameUrlHandlerMapping系列
猿蜕变系列8——一文搞懂Interceptor操纵姿势
看过之前的蜕变系列文章,相信你对springMVC有了一定的认识。对springMVC的文件上传,也有了一定的认识。今天我们来开启新讨论,讲一讲springMVC的Interceptor拦截器怎么去处理web层面通用逻辑。
山旮旯的胖子
2020/07/28
4500
猿蜕变系列8——一文搞懂Interceptor操纵姿势
推荐阅读
相关推荐
不讲废话,全程干货,0基础带你学习SpringMVC拦截处理器
更多 >
交个朋友
加入架构与运维学习入门群
系统架构设计入门 运维体系构建指南
加入架构与运维工作实战群
高并发系统设计 运维自动化实践
加入前端学习入门群
前端基础系统教学 经验分享避坑指南
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档