前言
作为一名有多年开发经验的老司机,每次翻看 Spring 源码都让我感叹:"这哪是框架,分明是设计模式的百科全书!"
有些小伙伴在工作中可能只会用@Autowired,却不知背后藏着多少精妙设计。
今天这篇文章跟大家一起聊聊 Spring 中最常用的 10 种设计模式,希望对你会有所帮助。
1 模板方法模式:流程骨架大师
场景:处理重复流程但允许细节变化 Spring 应用:JdbcTemplate、RestTemplate等
// 伪代码展示模板方法核心public abstract class 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);}
复制代码
为什么用:
复用资源管理(连接获取/释放)等通用逻辑
允许子类只关注业务差异(如结果映射)
思考:当你写重复流程时,想想能否抽出模板骨架
2 工厂模式:对象出生管理局
场景:解耦对象创建与使用 Spring 应用:BeanFactory核心接口
public interface BeanFactory { Object getBean(String name); <T> T getBean(Class<T> requiredType);}
// 实现类:DefaultListableBeanFactorypublic class UserService { // 使用者无需关心Bean如何创建 @Autowired private OrderService orderService; }
复制代码
设计精髓:
隐藏复杂的对象初始化过程(如循环依赖处理)
统一管理对象生命周期(单例/原型等作用域)
类比:就像点外卖不需要知道厨师怎么做菜
3 代理模式:隐形护卫
场景:无侵入增强对象功能
Spring 应用:AOP 动态代理
// JDK动态代理示例public class 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@Componentpublic class LogAspect { @Before("execution(* com.example.service.*.*(..))") public void logMethodCall(JoinPoint jp) { System.out.println("调用方法: " + jp.getSignature().getName()); }}
复制代码
动态代理两板斧:
JDK 代理:基于接口(要求目标类实现接口)
CGLIB 代理:基于继承(可代理普通类)
价值:业务逻辑与横切关注点(日志/事务等)彻底解耦
4 单例模式:全局唯一指挥官
场景:减少资源消耗,保证全局一致性
Spring 实现:Bean 默认作用域
// 源码片段:AbstractBeanFactorypublic 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机制
// 1. 定义事件public class OrderCreatedEvent extends ApplicationEvent { public OrderCreatedEvent(Order source) { super(source); }}
// 2. 发布事件@Servicepublic class OrderService { @Autowired ApplicationEventPublisher publisher; public void createOrder(Order order) { // 业务逻辑... publisher.publishEvent(new OrderCreatedEvent(order)); }}
// 3. 监听事件@Componentpublic class EmailListener { @EventListener public void handleOrderEvent(OrderCreatedEvent event) { // 发送邮件通知 }}
复制代码
优势:
事件源与监听器完全解耦
支持异步处理(加@Async注解即可)
6 策略模式:算法切换器
场景:动态选择算法实现
Spring 应用:Resource资源加载
// 资源加载策略族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
// 伪代码:处理多种Controllerpublic class 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实现等
复制代码
价值:
8 装饰器模式:功能增强包
场景:动态添加功能
Spring 应用:HttpServletRequest包装
// 典型应用:缓存请求体ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(rawRequest);
// 可在filter中多次读取bodybyte[] body = wrappedRequest.getContentAsByteArray();
复制代码
源码实现:
public class ContentCachingRequestWrapper extends HttpServletRequestWrapper { private ByteArrayOutputStream cachedContent; @Override public ServletInputStream getInputStream() { // 装饰原方法:缓存流数据 }}
复制代码
设计本质:通过包装器在不修改原对象基础上增强功能
9 建造者模式:复杂对象组装工
场景:分步构建复杂对象
Spring 应用:BeanDefinitionBuilder
// 构建复杂的Bean定义BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(UserService.class);builder.addPropertyValue("maxRetry", 3);builder.setInitMethodName("init");builder.setScope(BeanDefinition.SCOPE_SINGLETON);
// 注册到容器registry.registerBeanDefinition("userService", builder.getBeanDefinition());
复制代码
对比传统构造:
解决多参数构造的混乱(尤其可选参数多时)
构建过程更加清晰可读
10 责任链模式:拦截器的骨架设计
场景:解耦多步骤处理流程
Spring 应用:HandlerInterceptor拦截器链
// Spring MVC核心执行链public class HandlerExecutionChain { private final List<HandlerInterceptor> interceptors = new ArrayList<>(); // 执行前置处理(责任链核心) public boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) { for (int i = 0; i < interceptors.size(); i++) { HandlerInterceptor interceptor = interceptors.get(i); // 任意拦截器返回false则中断链条 if (!interceptor.preHandle(request, response, this.handler)) { triggerAfterCompletion(request, response, i); // 清理已完成 return false; } } return true; }}
复制代码
实战配置:
@Configurationpublic class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 构建责任链 registry.addInterceptor(new LogInterceptor()).order(1); registry.addInterceptor(new AuthInterceptor()).order(2); registry.addInterceptor(new RateLimitInterceptor()).order(3); }}
// 独立拦截器实现public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) { if (!checkToken(req.getHeader("Authorization"))) { res.sendError(401); // 认证失败 return false; // 中断链 } return true; // 放行 }}
复制代码
设计价值:
开闭原则:新增拦截器无需修改现有代码
单一职责:每个拦截器只关注单一功能
动态编排:通过order()灵活调整执行顺序
流程控制:任意节点可中断或继续传递
典型反模式:在拦截器中注入其他拦截器,这将破坏责任链独立性,导致循环依赖!
总结
解耦的艺术工厂模式解耦创建/使用,观察者模式解耦事件/处理
扩展性的智慧策略模式支持算法扩展,装饰器模式支持功能扩展
复杂性的封装模板方法封装流程,建造者模式封装构建
性能的权衡单例模式减少资源消耗,代理模式按需增强
最后送给小伙伴们的建议:不要为了用模式而用模式。
就像 Spring 的作者 Rod Johnson 说的:"优雅的代码不是模式的堆砌,而是恰到好处的抽象。"
当你下次写代码感到别扭时,不妨想想这些经典模式,或许能豁然开朗。
文章转载自:苏三说技术
原文链接:https://www.cnblogs.com/12lisu/p/18930715
体验地址:http://www.jnpfsoft.com/?from=001YH
评论