2023年Stack Overflow调研显示,78%的Spring开发者每天打交道的注解背后,藏着他们从未意识到的设计模式。这不是框架的阴谋,是文档没告诉你怎么"透视"代码。
一个典型场景:你在Service层加@Autowired,觉得只是"自动注入"。但Spring容器里发生的是工厂模式(Factory Pattern)的完整链路——BeanDefinition解析、依赖图谱构建、代理对象生成。你写的每一行"声明式"代码,都是命令式逻辑的压缩包。
单例模式:Spring的默认人格
Spring容器中的Bean默认就是单例。这不是配置项,是架构假设。
但这里有个陷阱:很多人把"单例"和"Spring单例"混为一谈。
GoF的单例模式保证一个类只有一个实例;Spring的单例保证一个Bean定义在一个容器上下文里只有一个实例。后者作用域更小,却更实用——它允许你在不同上下文(比如父子容器)里存在"同名不同命"的Bean。这种设计让模块化部署成为可能,代价是你得理解@Scope的隐性边界。
代理模式:AOP的隐身衣
@Transactional可能是Java世界最被误用的注解。开发者以为它"开启事务",实际上它开启的是动态代理。
Spring用JDK动态代理(接口基于)或CGLIB(类基于)包裹你的Bean。方法调用先经过代理层,事务管理器判断是否需要切入。同一个类内部方法互相调用时事务失效,根源就在这里——this指针绕过了代理层。
这个细节每年在GitHub上产生超过2000个"事务不生效"的issue,解法却简单得离谱:注入自己,或者改用AspectJ编译期织入。
模板方法模式:JdbcTemplate的暴力美学
写过原生JDBC的人都知道资源关闭的噩梦。JdbcTemplate把这套流程焊死在骨架里:获取连接、执行回调、处理异常、释放资源,一气呵成。
你只需实现RowMapper或PreparedStatementSetter,把变化的部分插进固定流程。这种"好莱坞原则"(别调用我们,我们会调用你)在Spring Data里随处可见——JpaRepository的方法命名解析、RedisTemplate的序列化钩子,都是同一套思维的不同皮肤。
观察者模式:事件机制的暗线
Spring 4.2之后,@EventListener让异步解耦变得廉价。但多数人没意识到:这是观察者模式(Observer Pattern)的工程化实现。
应用上下文本身就是事件广播器,ApplicationEventMulticaster负责分发。ContextRefreshedEvent、ContextClosedEvent这些内置事件,构成了Spring生命周期的隐形骨架。自定义事件只需继承ApplicationEvent,但真正的技巧在于设计事件粒度——太细导致广播风暴,太粗失去解耦意义。
Netflix的Spring Cloud套件里,配置刷新事件EnvironmentChangeEvent能触发上百个微服务实例的热更新,靠的就是这套机制的横向扩展。
Spring 6.1引入的AOT(提前编译)正在改写部分模式的实现方式。当原生镜像成为默认选项,动态代理会让位给静态织入,依赖注入的反射操作会被编译期生成代码取代。那些藏在注解里的设计模式,正在以另一种形态重生。
你最近一次调试Spring源码,是在解决什么问题?
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.