我见过一个生产环境的Spring Boot项目,200多个接口,日均调用量3000万次,代码量超过15万行。打开第一屏我就关了IDE——不是看不懂,是太熟悉了,熟悉到让我想起自己三年前写的垃圾。

这不是个例。我翻遍了GitHub上标星过千的Spring Boot开源项目,发现70%以上都在重复同一种错误:把"能跑"当成"能维护",把"功能全"当成"设计好"

那个让我窒息的下午

那个让我窒息的下午

项目结构看起来无懈可击。controller、service、dao三层分明,每个包都规规矩矩。但点开任意一个service层,3000行的类文件,80%是if-else嵌套,业务逻辑和数据库查询缠成一团。

最讽刺的是注释。"// TODO: 重构"——时间戳是2021年3月。三年过去,这个TODO成了遗产。

我拉了一下git记录,过去12个月有47位开发者提交过代码,平均每人改了不到5个文件。不是大家懒,是不敢动。一个字段的改名需要同步修改12个地方,漏一个就是线上故障。

技术负责人跟我吐槽:「我们招了三个P7,两个月全跑了。不是钱的问题,是他们说代码在"吞噬灵魂"。」

企业级幻觉:我们到底在迷信什么

企业级幻觉:我们到底在迷信什么

Spring Boot的官方文档有187页,但大多数人只看了前20页的"快速开始"。剩下的167页讲什么?监控、安全、配置分离、优雅关闭——这些被统称为"生产就绪"(Production Ready)的能力。

我见过太多团队把"用了Spring Boot"等同于"做了微服务"。实际上他们只是把单体应用拆成了三个jar包,数据库还是同一个,调用链全靠HTTP硬连,故障时互相拖死。

一个真实的对比:某电商公司两套系统并行,A组用"传统"Spring Boot写法,B组严格执行Spring Boot Actuator + 配置中心 + 熔断隔离。618大促时,A组系统扩容花了4小时,B组7分钟。差距不在框架,在用法。

企业级的真正成本不是开发,是认知债务。每个临时方案都在透支未来的调试时间,每个"先上线再说"都在培养下一个不敢碰代码的工程师。

三个正在毁掉项目的习惯

三个正在毁掉项目的习惯

第一个习惯叫"配置硬编码"。数据库连接串写在application.yml里,然后提交到Git。测试环境、预发环境、生产环境各有一个分支,合并时冲突不断。Spring Boot从1.0就支持的外部化配置,用了9年还没普及。

第二个习惯更隐蔽:滥用@Autowired。字段注入写起来快,测试时噩梦开始。你无法mock依赖,只能启动整个Spring上下文,单元测试跑成集成测试,一次构建20分钟。

第三个习惯是"异常吞噬"。try-catch块里写个e.printStackTrace(),或者干脆空catch,接口返回200但数据是错的。调用方以为是成功,其实是沉默的失败。Spring Boot的全局异常处理机制(@ControllerAdvice)明明三行代码就能解决,非要每个方法自己try。

我统计过那个15万行项目里的异常处理:空catch块占比31%,printStackTrace占比44%,真正记录到日志系统的不到四分之一。线上出问题,日志里找不到痕迹,只能加日志重新发布——这是2024年的开发体验。

为什么改不动

为什么改不动

技术债的可怕之处不是"有",是"看不见"。产品经理看需求列表,老板看上线频率,没人看代码的腐化速度。直到某天一个简单需求评估出"人月",大家才惊觉系统已经僵化。

那个15万行项目的CTO跟我算过账:重构需要6个月,期间不能加新功能,还要保持线上稳定。董事会不会批准。于是继续堆代码,等待下一次"人月"时刻。

这不是技术问题,是组织问题。Spring Boot本身是中性的,它既能让好团队更快,也能让烂团队更烂。

我见过一个5人小团队,严格执行领域驱动设计(DDD),核心域代码测试覆盖率91%,每次发布自动回滚时间小于30秒。他们也用Spring Boot,但用法和那个15万行项目完全不同。

一个可能的出路

一个可能的出路

Spring Boot 3.2去年发布,原生镜像(GraalVM Native Image)支持正式GA,启动时间从秒级降到毫秒级,内存占用砍半。但我问了十几个团队,用过的为零。不是技术不成熟,是现有代码根本跑不起来——反射滥用、动态代理嵌套、类路径扫描写死,全是原生镜像的克星。

这像个隐喻:我们以为在驾驭技术,其实是被技术债务绑架。

那个"吞噬灵魂"的项目后来怎么样了?CTO走了,技术负责人升了,新招的毕业生继续往3000行的service里加if-else。系统还在跑,3000万次日调用也没崩。只是每次有人离职,交接文档里都会多一行:"不建议修改XX模块,历史原因"。

历史原因。这四个字在代码库里出现了127次。

你现在的项目里,"历史原因"出现了多少次?