
1. 项目配置的整体思路与核心矛盾做SpringBoot项目配置这件事说难不难说简单也绝对不简单。我见过太多人卡在一个莫名其妙的报错上折腾半天最后发现只是配置文件里多了一个空格也见过有人把所有配置都堆在一个application.yml里环境一切换就崩得稀里哗啦。说白了SpringBoot项目配置的核心矛盾就两个怎么让项目在不同环境下稳定跑起来怎么让配置本身可维护、可扩展。先把这个事情拆开看。SpringBoot最讨人喜欢的地方就是“约定大于配置”——它默认帮你准备好了大部分开箱即用的东西比如内嵌的Tomcat、自动装配机制、统一的事务处理。但恰恰是这个默认机制让很多人忽略了配置层的设计。你真正动手配置一个项目时会发现配置文件不是写给别人看的是写给未来的自己看的。三个月后你再打开这个项目如果靠回忆才能想起来某个参数是干嘛的那这个配置就是失败的。我这几年经手的项目里有校园考勤管理系统这类典型的毕设项目也有企业级的数据处理平台还有嵌入了前端静态资源的单体应用。它们虽然规模不同但配置的核心路径出奇一致环境准备、项目骨架、核心配置文件、组件接入、部署切换。这篇文章我就按这条线走一遍把我踩过的坑和验证过有效的做法全部摊开给你一个可以直接“抄作业”的完整方案。读这篇文章之前你要知道SpringBoot的配置工作不是简单的填表它背后涉及Java环境、构建工具、依赖管理、外部组件协同这一整条链。所以我不打算只讲application.yml里那几个参数我会从JDK版本选择开始一直讲到部署时端口怎么处理、前端打包产物怎么塞进静态资源目录。这样无论你是在做毕设、接外包还是维护公司老项目都能找到对应自己处境的那一段。2. 环境层的配置JDK、Maven与IDE联调2.1 JDK版本选择背后的那些门道很多新手上来就装个最新的JDK结果SpringBoot项目一启动就报错翻来覆去找不到原因。这里要先明确一点SpringBoot的每个大版本都对应着特定的JDK基线。SpringBoot 2.x系列官方要求Java 8以上但你如果非要拿Java 8跑SpringBoot 3.x那直接编译都过不去因为SpringBoot 3.x是基于Jakarta EE规范重写的最低要求Java 17。我个人的经验是做新项目直接选JDK 17配合SpringBoot 2.7.x或3.x这是目前最稳妥的组合。JDK 8虽然兼容SpringBoot 2.x早期版本但你后续接一些新组件时会发现各种不兼容比如某些版本的MySQL驱动、Redis客户端在JDK 8下的表现就差强人意。JDK 8时代做开发安装包只有一百多兆解压配个环境变量就能用到了JDK 17、21你还要注意一个坑——如果是通过压缩包安装别忘了解压后检查bin目录下有没有java.exe某些精简版会自带JRE但面向开发最好还是装完整JDK。环境变量配置这块我已经帮无数人排查过问题。JAVA_HOME必须指向JDK的安装根目录不是bin目录。Path里要追加的是%JAVA_HOME%\binWindows或$JAVA_HOME/binLinux/Mac。配置完了一定要在命令行验证——打开终端输入java -version和javac -version两个命令都有输出且版本一致才算成功。最常见的问题就是只配了java能运行javac找不到这说明你装的是JRE而不是JDK或者JAVA_HOME指错了位置。2.2 Maven的settings.xml决定了你能走多远说句实在话Maven配置比JDK更容易让人崩溃。因为你本地仓库默认在国外服务器不配镜像的话下载依赖的速度能让你怀疑人生。我在公司的内网环境里摔过跟头也在自己电脑上体验过一把鼻涕一把泪等依赖下载的日子最后发现问题的关键都在settings.xml这个文件上。本地仓库的位置默认在用户目录下的.m2/repository你可以保持默认但建议在settings.xml里显式指定一个路径比如D:/maven-repository这样以后想清缓存、迁移环境都有明确目标。更重要的配置是镜像源国内项目我建议直接用阿里云仓库配置方式是在settings.xml的mirrors节点里添加mirror idaliyunmaven/id mirrorOfcentral/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirror这里有个容易踩的细节mirrorOf的值如果是*会把所有仓库请求都拦截到镜像上如果是central只镜像中央仓库。我推荐后者因为有些私有仓库或者第三方仓库比如某些公司内部的构件库不需要走镜像全部拦截反而会出问题。Maven安装完成后记得配置MAVEN_HOME并把bin目录加入Path。验证方式是在命令行执行mvn -v看到版本信息就说明环境没问题。我还遇到过一种情况命令行里Maven能用但IDEA里构建报错这通常是IDEA没有正确识别Maven的安装路径和settings.xml。你需要在IDEA的Build Tools Maven设置里把User settings file指定到你实际使用的配置文件路径。2.3 IDEA里配置SpringBoot运行服务的细节现在IDE的选择上IntelliJ IDEA是毫无疑问的主流但很多人的IDEA配置是有问题的。最典型的一个场景你从Gitee或者GitLab上拉下来一个SpringBoot项目点击运行却发现启动类上有个红色的叉号或者启动后端口不对、环境是dev还是prod完全不按你的意愿来。先在File Project Structure里确认三件事Project SDK选的是不是你希望的JDK版本Project language level是否匹配Modules里的Java版本是否同步。这三处不一致的话编译阶段就会出现“无效的源发行版”之类的报错。接下来是运行配置。在IDEA的Run/Debug Configurations里SpringBoot项目通常选择Spring Boot类型而不是Application类型后者适合纯净的Java程序。这里你能配置的关键参数有Active profiles相当于指定spring.profiles.active比如填dev就加载application-dev.yml。VM options需要添加JVM参数时在这里写比如-Dfile.encodingUTF-8解决乱码问题。Environment variables有时候你不想在配置文件里写数据库密码可以通过这里传入环境变量SpringBoot支持${DB_PASSWORD}这种占位符用法。Port如果你用的内嵌Tomcat想临时改端口直接在application.yml里改server.port就行。但如果你不想污染配置文件可以在IDEA运行配置的Program arguments里加--server.port8081这样会覆盖配置文件里的值。很多人不知道的是Program arguments的优先级高于application.yml里的配置。这个特性在联调场景下特别实用——不需要重新打包只需在启动参数里指定端口和环境就能让同一个包跑出不同效果。3. 项目骨架与核心配置文件的构建3.1 初始化SpringBoot项目的几种方式和取舍新建SpringBoot项目常规做法是打开 Spring Initializr官网 填表单或者直接在IDEA里用内置的Spring Initializr生成。我自己的习惯是如果是接手老项目就在原有基础上改如果是全新开始就在IDEA里新建Spring Boot项目选好Group、Artifact、依赖自动生成pom.xml和启动类。这里有一个容易被忽略的选项——Spring Boot版本号怎么选。不要无脑选最新版去Github上看了release说明再定。比如热词里提到的“springboot版本太高”这个问题我碰上过不止一次。SpringBoot 3.x刚出那会儿很多配套的starters还没更新整合activemq、flink这些组件时就会遇到兼容性问题。稳妥的做法是选一个发布超过半年的稳定版本比如当前环境下3.2.x或者2.7.x等你确认所有依赖都能正常拉下来再升级也不迟。另外如果公司网络访问不了Spring Initializr或者你想完全离线创建一个项目可以在本地用Maven原型来生成mvn archetype:generate -DgroupIdcom.example -DartifactIddemo -DarchetypeArtifactIdspring-boot-starter-parent但这种做法生成的骨架可能不够完整我一般只在网络受限时用。还有个更好的代理方案在IDEA里把Spring Initializr的Server URL换成阿里云的镜像地址这样创建项目时依赖解析走国内网络就快多了。3.2 项目目录结构与配置文件的职责划分一个标准的SpringBoot项目目录结构里包含了src/main/java、src/main/resources、src/test/java这几个核心区域。很多教程只是简单带过但我想说的是这个结构本身就是在帮你管理配置复杂度。resources目录下放的是application.yml、logback.xml、mapper文件等如果你的代码里出现了硬编码的IP地址、账号密码、业务开关那属于设计层面的问题。我用一个实际案例来说明。之前做一个“基于SpringBoot Vue的商品管理系统”的项目前后端分离。后端需要配置数据库连接、Redis、文件上传路径、日志级别。我最初的配置文件是单个application.yml后来改成了这样一套src/main/resources/ ├── application.yml ├── application-dev.yml ├── application-prod.yml └── banner.txtapplication.yml里只放公共配置比如应用名称、端口默认值、Spring框架的基础配置、MyBatis的全局配置。application-dev.yml放开发环境的数据库地址、缓存配置、日志级别为DEBUG、前端联调接口地址等。application-prod.yml则用环境变量占位符替代敏感信息比如${DB_USERNAME}、${DB_PASSWORD}保证密码不进版本库。这样拆分的核心逻辑是公共配置与差异配置分离敏感配置与普通配置分离。你启动项目的时候通过spring.profiles.active指定加载哪套环境配置切换环境只需要改一个参数。这个方法在我后续维护多个环境的时候节省了大量的时间。3.3 一网打尽application.yml里不得不说的核心项很多人对application.yml的理解停留在“填数据库连接”这个层面实际上它管的事情多得很。我从实际项目中提炼出一份“必配清单”按优先级排列应用基础配置spring: application: name: demo-service server: port: 8080 servlet: context-path: /apispring.application.name非常关键。如果你引入了Spring Cloud组件服务名就是注册中心里显示的名字就算没有微服务这个名字也会出现在日志、监控里方便定位服务来源。server.servlet.context-path是接口前缀加上后所有的访问路径都会带/api前缀想省事的话可以不加但和前端联调时有个统一前缀更清晰。数据源配置spring: datasource: url: jdbc:mysql://localhost:3306/demo?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver这里的URL里藏着好几个坑。useUnicodetruecharacterEncodingutf8解决中文乱码useSSLfalse是因为大部分本地MySQL没有配置SSL证书不关掉会报警告甚至连接失败serverTimezoneAsia/Shanghai必须加因为新版MySQL驱动要求显式指定时区否则报Connection refused或者The server time zone value的错误。日志配置SpringBoot默认用Logback你可以在application.yml里直接设置日志级别但控制不了文件输出格式和滚动策略。我一般会单独建一个logback-spring.xml里面按需配置输出路径、按天滚动、保留天数。有一点要注意logback-spring.xml和logback.xml虽然只差一个spring但前者支持SpringBoot的profile特性可以根据环境加载不同配置。Jackson序列化配置这个配置算是我后期才加上去的因为吃过亏。前后端交互时LocalDateTime默认序列化成数组格式前端解析要额外处理。在配置里显式声明格式能省掉不少麻烦spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8上传文件大小限制如果你做一个带头像上传、文件导入功能的管理系统默认的1MB上传限制会让你崩溃。需要手动调大spring: servlet: multipart: max-file-size: 50MB max-request-size: 100MB3.4 Banner不只是一个装饰品热词里有“springboot banner 在线”和“springboot banner生成器”这看起来像娱乐向的小功能但我告诉你它在实际开发里有个隐藏用途标识服务版本。我在banner.txt里写入的除了ASCII艺术字还有版本号、环境、启动时间这样每次部署后打开日志就能第一眼确认这个进程跑的是哪个版本、哪个环境。尤其在多环境混用出问题的时候这个信息能让你少掉好几根头发。生成banner最简单的方式是访问 patorjk.com/software/taag 这类在线工具输入文字生成ASCII字符图案然后粘贴到src/main/resources/banner.txt。如果想关闭默认的SpringBoot banner有时候集成测试需要纯净输出在application.yml里加一行spring.main.banner-mode: off即可。4. 组件整合与外部依赖的配置实操4.1 数据库相关的完整接入过程一个SpringBoot项目接入MySQL看起来简单真正操作时你会发现版本匹配是最大的拦路虎。我举一个真实的排查案例有次拉了个老项目pom里用的MySQL驱动版本是5.1.47但本地MySQL装的是8.0启动时报ClassNotFoundException: com.mysql.jdbc.Driver。原因很好理解老版本的驱动类名是com.mysql.jdbc.Driver新版本改成了com.mysql.cj.jdbc.Driver而且通讯协议也变了。解决办法是升级依赖到mysql-connector-j新版驱动坐标dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency如果你用的是SpringBoot 2.7.x这个依赖版本由Spring Boot的依赖管理统一控制不需要手动指定版本号。但如果你是手工创建的项目就得自己查对应版本。连接池我推荐直接使用HikariCPSpringBoot 2.x之后默认就是它性能好得没话说。如果想微调可以在配置里加spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000需要提醒的是maximum-pool-size不是越大越好。数据库连接数是有限资源过大的池子反而会因为线程竞争拖垮性能。我一般压测后根据实际并发数调整通常10~20之间够用。4.2 非关系型数据库与消息队列的接入要点项目里用到Redis的场景非常多比如缓存热点数据、分布式锁、验证码存储。接入Redis的第一步是在pom里引入spring-boot-starter-data-redis然后在配置里写明地址和密码spring: redis: host: localhost port: 6379 password: 123456 database: 0 lettuce: pool: max-active: 8 max-idle: 8 min-idle: 0这里有个容易踩的坑SpringBoot 2.x之后默认使用Lettuce连接池但这个连接池并不是自动开启的你得显式引入commons-pool2依赖否则max-active之类的配置根本不会生效。我见过有人配置了连接池参数但压测时连接数还是蹭蹭往上涨就是因为少了这个依赖。消息队列的话ActiveMQ在传统行业项目里还有不少存量SpringBoot整合ActiveMQ需要引入spring-boot-starter-activemq。如果用的是嵌入式模式SpringBoot会自动启动一个内置的ActiveMQ Broker如果连接外部Broker要在配置里指定broker-urlspring: activemq: broker-url: tcp://localhost:61616 user: admin password: admin整合JMS的时候还要注意JmsListener注解作用的消费者方法默认并发消费者是1。如果你期望高吞吐需要在DefaultJmsListenerContainerFactory里调整并发数这是个性能优化的关键点很多人不会特意去配。4.3 前端打包产物塞进SpringBoot后端的正确姿势热词里有“vue打包放进springboot中”这个场景在毕设和单体应用中太常见了。最常见的做法是Vue项目执行npm run build后把生成的dist目录下的所有文件复制到SpringBoot的src/main/resources/static目录下。这样SpringBoot启动后访问http://localhost:8080就能直接看到前端页面后端接口也走同一个端口不会有跨域问题。但直接复制会有几个坑。第一个是路由模式问题Vue如果用history模式mode: history刷新一个子路由页面时会404因为SpringBoot的静态资源处理找不到对应的前端路由。解决方案有两个一是把Vue路由改成hash模式URL里带#二是写一个Controller做统一转发把所有非接口的请求转发到index.html。我倾向于后者体验更好Controller public class ForwardController { RequestMapping(value {/, /login, /index, /user/**}) public String forward() { return forward:/index.html; } }第二个坑是接口路径冲突。前端打包后请求后端接口的路径如果是/api/开头而SpringBoot的Controller也映射了同样的路径静态资源处理器就会和控制器产生歧义。我建议前后端约定统一的路由前缀后端Controller统一加RequestMapping(/api)前端代理和打包后的请求也走这个前缀基本能规避掉。第三个坑是Vue打包发布时静态资源引用路径。Vue默认打包后的JS、CSS引用路径是根路径/如果SpringBoot设置了server.servlet.context-path: /api这些静态资源会全部404。解决办法是在Vue项目根目录的vue.config.js里设置publicPath: ./这样就变成了相对路径不管部署在什么子路径下都能正确加载。4.4 Git与版本管理相关的协作配置热词里有“git安装及配置教程”虽然它不是SpringBoot专属但项目协作中绕不开。我简单说说和SpringBoot项目相关的Git配置要点。首先是.gitignore文件SpringBoot项目里必须忽略target/目录、IDE的.idea/、.classpath、.project、*.iml这些文件以及本地的application-dev.yml如果有敏感信息也不能提交。我见过同事把数据库密码和云服务密钥提交到公共仓库等发现时只能全体改密码这个教训很深刻。其次多分支环境配置的实践经验是master分支对应生产环境配置develop分支对应测试环境配置功能分支可以在各自的配置里指向本地环境。但这样维护起来很累——每次改个数据库密码都要同时改好几个分支。我更推荐的做法是配置统一放在代码仓库里只放模板文件比如application.yml.example真实的配置由各自的部署系统注入环境变量或者从Git的私有仓库拉取秘密文件。这样配置变更只走一次发布流程而不是改完代码再改配置。5. 部署层面的配置经验与多环境切换5.1 打包时如何控制环境参数SpringBoot项目作为单体应用部署打包命令很简单mvn clean package。但是打出来的jar包默认加载的是application.yml里的配置而生产环境和开发环境的配置往往差异巨大。我的经验是打包时用-Dspring.profiles.activeprod指定激活的环境mvn clean package -Dspring.profiles.activeprod但这里有个细节-D参数是传给Maven的不是直接传给SpringBoot的。如果你是打成war包部署到外部Tomcat或者打jar包直接java -jar运行正确的方式是在运行时指定java -jar demo-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod --server.port8082运行时命令行参数的优先级高于配置文件这个特性要记住了它意味着你可以不用重新打包就切换环境、改端口、改数据库地址。在实践中有个技巧把启动参数放在一个start.sh脚本里这样每次部署只需改脚本不用动代码#!/bin/bash nohup java -Xms512m -Xmx1024m -jar demo.jar --spring.profiles.activeprod --server.port8080 app.log 21 echo App started with pid $!-Xms512m -Xmx1024m是初始堆内存和最大堆内存的配置。生产环境里我一般根据服务器物理内存来决定如果机器有4GB内存给应用分配1GB是比较合适的如果应用有大量缓存可以适当调大。这个参数直接影响GC频率和应用稳定性不能拍脑袋乱填。5.2 端口、路径与代理配置的联动部署SpringBoot到服务器上端口问题经常和Nginx配置纠缠在一起。热词里有“本地虚拟机多端口nginx开发环境多站点自定义域名配置”这个场景说的是开发环境用Nginx做反向代理把不同域名或不同端口转发到不同的后端服务。最常见的配置拓扑是Nginx监听80端口根据路径或域名转发给SpringBoot应用。比如前端访问http://yourdomain.com/api/Nginx把/api/前缀的请求转发到http://127.0.0.1:8080/server { listen 80; server_name yourdomain.com; location /api/ { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location / { root /var/www/dist; try_files $uri $uri/ /index.html; } }这里面有两点必须注意。第一proxy_pass的URI末尾有没有斜杠决定了路径是否被替换。proxy_pass http://127.0.0.1:8080/;会把/api/user/list转发成/user/list如果不加斜杠则转发为/api/user/list。这个细节取决于你后端Controller是否带/api前缀需要前后端对齐。第二proxy_set_header X-Forwarded-For可以让后端的日志里记录到真实客户端IP方便排查问题。Nginx配置修改后执行nginx -t检查语法然后nginx -s reload重载。我在开发环境用docker run跑Nginx时还要注意容器的-p端口映射和内部conf文件挂载路径别把容器内外的目录搞混了。5.3 外部化配置与配置中心的使用思路随着项目变大配置文件里的参数越来越多简单地在application.yml里写死已经不够用了。比如微服务架构下每个服务的数据库地址、中间件地址都是不同的而且有些参数需要运行时动态调整。这时候就要考虑外部化配置或者配置中心。SpringBoot原生支持通过环境变量、ConfigurationProperties绑定自定义配置类、spring.config.import引入外部配置文件等机制。比如你可以把application-prod.yml放到jar包外面的config/目录SpringBoot启动时会自动读取./config/下的配置并覆盖内置配置。如果用了Spring Cloud Config或者Nacos配置文件可以统一放在配置中心本地配置就只需要一行spring: config: import: nacos:demo-service.yaml配置中心的优势在于修改配置不需要重启服务配置中心会推送变更到客户端。但引入配置中心也意味着多了一套要维护的组件如果只是几个微服务的小项目我建议不要一上来就上配置中心先把SpringBoot原生的多环境配置用好等真正有动态配置的需求时再扩展。很多人把简单问题复杂化了配置文件的“够用”比“高级”更重要。6. 典型问题排查实录与避坑手册6.1 最常见的“端口被占用”怎么处理SpringBoot启动报“Port 8080 was already in use”这个错误每个做后端的人都遇过。第一次遇到时我直接在IDEA里关掉了所有项目——结果发现是Windows系统自身的服务占了端口。后来掌握了正确的排查姿势Windows下执行netstat -ano | findstr :8080Linux/Mac下执行lsof -i :8080拿到占用端口的进程PID后Windows用taskkill /PID pid /F杀掉Linux用kill -9 pid。但这里要提醒一句在服务器上不要盲目杀进程先确认这个进程是不是别人的服务。有次我在测试服务器上杀掉了一个“占端口”的进程结果是某个同事正在批量跑数据的任务影响不小。稳妥的做法是先看进程名和启动命令确认是自己的服务再处理。6.2 中文乱码的全面整治方案中文乱码问题在SpringBoot项目里是个常见的综合问题来源可能是数据库连接参数、文件编码、HTTP响应编码、控制台输出编码等等。我总结了一套排查顺序先看配置文件spring.datasource.url里有没有characterEncodingutf8server.servlet.encoding.charsetUTF-8新版SpringBoot可以用server.servlet.encoding.enabledtrue。再看IDEA的编码设置Settings Editor File Encodings把Global Encoding、Project Encoding、Properties Files都改成UTF-8。再看运行配置的VM options加上-Dfile.encodingUTF-8。如果接口返回的JSON里的中文是???那很可能是在HTTP响应阶段编码出问题了。可以在Controller的方法上显式指定produces application/json;charsetUTF-8或者全局配置spring.jackson.default-property-inclusion和server.servlet.encoding。如果在Linux服务器上查看日志中文乱码确认日志文件本身的编码以及启动脚本里有没有-Dfile.encodingUTF-8。一个容易被忽视的点MySQL数据库的字符集排序规则也要统一。建库的时候执行CREATE DATABASE demo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;utf8mb4兼容emoji和更多特殊字符比utf8更省心。光改连接URL而数据库本身就是latin1的话照样乱码。6.3 SpringBoot版本不兼容引发的连锁反应热词里专门列了“springboot版本太高”我深有感触。SpringBoot 3.x发布后很多老项目在升级过程中会遇到下面这些问题javax.变成 jakarta.**SpringBoot 3.x把包名从javax.servlet改成了jakarta.servlet如果你的代码里有import javax.servlet.*编译直接失败。升级方法是在IDEA里全局替换包名。SpringFox 2.x不兼容SpringFox只支持到SpringBoot 2.6左右如果你在SpringBoot 2.7以上集成Swagger时会碰到NullPointerException解决方法是用springdoc-openapi替代SpringFox。配置属性的变更一些配置项的key改名字了比如spring.redis.*变成了spring.data.redis.*SpringBoot 3.x如果直接复制老项目的配置会静默失效——SpringBoot会打日志提醒但不报错于是你发现Redis连接一直不成功实际上是配置没生效。CGLIB代理的默认行为变化SpringBoot 2.x默认使用CGLIB代理spring.aop.proxy-target-classtrue是默认值这一点你在用Configuration类时可能会感知到——配置类不再允许是final的。我的建议是除非有明确的新特性需求不要为了“新版”而盲目升级。生产环境里稳定的组合比如SpringBoot 2.7.x JDK 8/11/17 MySQL 8 MyBatis 3.5.x已经经过大量项目验证。如果非升不可先把依赖版本逐一对照特别是数据库驱动、Redis客户端、消息队列客户端这些外部组件。6.4 敏感信息如何安全地放进配置最后一个不能回避的问题是密码、密钥、云服务的AccessKey到底该怎么管。把明文密码直接写在application.yml里再提交到公共仓库这个是绝对的红线我见过有些培训班项目就这么干上了生产才发现仓库是公开的。几个常规做法供参考环境变量注入${DB_PASSWORD}占位符会从系统环境变量读取不写入配置文件。服务器上通过export DB_PASSWORDxxx设置或者写在启动脚本里。Jasypt加密引入jasypt-spring-boot-starter配置里写ENC(xxx)密钥通过环境变量传入。这样即使配置文件泄露看到的也是密文。配置中心管理Nacos或Spring Cloud Config支持配置加密存储和权限控制适合多服务的场景。本地开发配置不下发生产用.gitignore忽略真实配置文件仓库里只保留.example模板。这几种方式我从轻到重排了个序实际项目中不要一开始就追求最复杂的方案而是看你的部署规模和风险承受能力。做毕设或者个人项目环境变量加.gitignore就够用了。7. 从框架配置到项目交付的最后一公里SpringBoot项目做完配置最大的成就感不是启动那一瞬间看到端口跑起来而是后续的每一次迭代、每一次部署都顺风顺水。总结一下我个人在这些年配置经验中反复验证过的几个习惯配置文件一定要分层公共的、环境的、敏感的彼此隔离启动参数尽量参数化保证同一个jar包在不同环境下能灵活运行每次变更配置后先启动再确认不要一口气改十几个参数然后一次性启动那样出了问题根本没头绪排查。还有一个小习惯很值得分享每次新接一个SpringBoot项目先在干净环境里跑通一个最小可运行版本再开始改动。很多人喜欢把项目拉下来后直接改自己的业务代码结果我的建议是宁可多花半小时把整个链路先跑通看看到底能起来、接口能不能访问、数据库能不能连上再开始动手。这样一开始就把基础环境固定住后面的所有问题都归因到业务代码而不是环境配置。配置工作看似琐碎但它决定了项目能走多远。一个配置混乱的SpringBoot项目哪怕业务代码写得再漂亮上线的时候也会变成定时炸弹。反过来一份结构清晰、参数收敛的配置能让整个团队在部署时省掉大量的沟通成本和时间成本。把这篇文章里的经验带回到你手头那个项目上去重新审视一下自己的配置文件你会发现能优化的地方比想象中要多得多。