
一个基于Spring Boot与Spring Cloud的实战项目
在入职新公司的第一天,我便接手了一个现有的 Spring Boot项目 进行开发。在快速熟悉代码的过程中,发现了一些在项目配置、代码规范与部署流程上值得探讨的典型问题。
项目代码中发现的典型问题
1. 配置文件管理混乱
项目在读取配置时,同时使用了两个配置文件:一个位于WEB-INF目录下的内部配置,另一个是外部配置文件,后者用于覆盖前者的部分属性。



这种设计引发了一个疑问:既然最终会被覆盖,为何不全部使用外部配置?原因在于代码中获取属性时,部分键名加上了项目前缀,而另一部分则没有。如果全部移至外部配置,会导致配置文件杂乱无序。但也不能完全写在内部配置,因为底层代码在获取外部配置值为空时会抛出异常。这是由于Properties类底层使用的HashTable的put方法不允许value为null。
prop_c.setProperty(key, value); // 如果value从外部配置获取为空,则会抛出异常
// Properties 底层使用 HashTable
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
}
2. 硬编码问题
代码中存在大量硬编码的参数,例如在权限判断时直接使用字符串常量。这种做法降低了代码的可维护性,一旦权限标识需要调整,修改的工作量和出错风险都会很大。
role.haveRole("ADMIN_USE") // 权限标识被硬编码
3. 日志打印不规范
项目中System.out.println和日志框架(如SLF4J)混合使用,且异常日志处理有待优化。


上图所示的异常打印方式,仅输出了错误信息,缺少完整的堆栈轨迹,这在生产环境排查复杂问题时非常不便。虽然e.getMessage()可能简洁,但在多数生产场景下,打印完整的堆栈信息更能快速定位根源。此外,若非需要针对不同异常类型进行差异化处理,捕获通用的Exception通常已足够。更重要的是,应统一使用日志框架而非System.out.println,以确保日志能被正确地收集、归档和检索。
4. 代码提交与生产部署流程缺失
项目缺少严格的代码审查和技术经理把关环节。生产环境的部署包可以由个人直接发布,这极易导致生产环境与本地开发环境,甚至与数据库的版本、数据产生不一致。数据库脚本的同步是生产部署中最容易被遗漏的步骤之一。例如,有一次因为文件上传模板已更新但未同步至生产数据库,导致问题在开发环境难以复现,排查过程异常曲折。
5. 生产数据库变更随意
对生产数据库的更改缺乏严格的流程控制和审计,完全依赖于开发人员的个人自觉与经验,存在较高的操作风险和数据安全隐患。
6. Maven依赖引用方式存疑
在管理项目依赖时,遇到了一个令人困惑的情况:一个公司内部的公共模块,其pom文件中定义的依赖,并非通过打包成jar并提供给其他项目引用,而是要求其他项目直接以<type>pom</type>的方式依赖该pom文件本身。

虽然可以通过如下方式解决依赖问题:
<dependency>
<groupId>com.company</groupId>
<artifactId>common-module</artifactId>
<version>1.0</version>
<type>pom</type>
</dependency>
但对于公司内部且实际需要引入其中具体jar包的模块,采用这种“pom继承”而非“jar依赖”的方式,其设计意图尚不明确。
针对现有问题的解决思路
对于新项目或重大升级项目,可以采取以下措施来规避上述问题:
-
统一配置管理:充分利用Spring Boot的application.yml或application.properties文件。开发环境无需拆分外部文件。对于生产环境,可以通过启动命令参数-Dspring.config.location指定外部配置文件路径,例如:
nohup java -Dfile.encoding=UTF-8 -Dspring.config.location=/config/application-prod.properties -jar your-app.jar &
或者考虑引入配置中心(如Nacos, Apollo)实现配置的动态管理和环境隔离,这属于 云原生/IaaS 和现代微服务架构的常见实践。
-
建立代码与流程规范:
- 代码层面:制定并遵守统一的代码规范,使用常量类或配置中心管理可变参数,统一使用日志框架并规范异常日志打印。
- 流程层面:建立强制性的代码审查(Code Review)机制。生产部署应通过标准的 运维/DevOps CI/CD流水线进行,确保数据库变更脚本与应用程序版本同步执行。任何对生产环境的直接操作(尤其是数据库)都必须经过申请、审批、记录的过程。
-
谨慎对待遗留代码重构:在已有项目上进行迭代开发时,如果没有充足的时间和测试保障,应优先考虑在原有结构上追加或修补,而非大规模重构,以控制风险。
总结与收获
尽管遇到了诸多挑战,但在分析这些问题的过程中,也能反向学习到一些具体的实现方式(例如原项目中JavaScript全局调用的写法,这为理解某些前端模式提供了案例)。面对遗留系统的技术债,在无法立即推动全面改革时,保持耐心、在局部改进,并推动团队建立共识,是更为务实的做法。