--- title: "04-多环境配置详解" created: 2025-12-02 tags: - 项目 aliases: - 多环境配置详解 --- # 多环境配置详解 ## **多环境配置** ### **配置文件优先级** ![[配置文件优先级-20cf86f9.jpg]] ### **激活环境的方式** ```yaml # ==================== 方式对比 ==================== # 方式1: application.yml 中配置(开发时常用) spring: profiles: active: dev # 方式2: 命令行参数(部署时常用) # java -jar app.jar --spring.profiles.active=prod # 方式3: 环境变量(容器化部署推荐) # export SPRING_PROFILES_ACTIVE=prod # java -jar app.jar # 方式4: JVM 参数 # java -Dspring.profiles.active=prod -jar app.jar # 方式5: 在 application.yml 中使用环境变量 spring: profiles: active: ${SPRING_PROFILES_ACTIVE:dev} # 默认 dev ``` ### **环境配置最佳实践** ![[环境配置最佳实践-8f458227.jpg]] --- ## **配置类与 YAML 的对应关系** ### **AppProperties 对应关系** ```java # YAML 配置 app: # @ConfigurationProperties(prefix = "app") name: project-name # -> AppProperties.name version: 1.0.0 # -> AppProperties.version debug: false # -> AppProperties.debug file: # -> AppProperties.file (FileConfig) max-size: 10485760 # -> FileConfig.maxSize allowed-formats: jpg,png # -> FileConfig.allowedFormats upload-path: /uploads # -> FileConfig.uploadPath jwt: # -> AppProperties.jwt (JwtConfig) secret: xxx # -> JwtConfig.secret expiration: 604800 # -> JwtConfig.expiration token-prefix: "Bearer " # -> JwtConfig.tokenPrefix header-name: Authorization # -> JwtConfig.headerName user: # -> AppProperties.user (UserConfig) max-password-retry: 5 # -> UserConfig.maxPasswordRetry max-login-device: 3 # -> UserConfig.maxLoginDevice lock-minutes: 30 # -> UserConfig.lockMinutes ``` ```text ┌──────────────────────────────────────────────────────────────────┐ │ 命名转换规则 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ YAML (kebab-case) Java (camelCase) │ │ ───────────────── ──────────────── │ │ max-size → maxSize │ │ allowed-formats → allowedFormats │ │ upload-path → uploadPath │ │ max-password-retry → maxPasswordRetry │ │ token-prefix → tokenPrefix │ │ │ │ 【Spring Boot 自动转换,两种写法都支持】 │ │ max-size = maxSize = MAX_SIZE(环境变量) │ │ │ └──────────────────────────────────────────────────────────────────┘ ``` ### **CorsConfig 对应关系** ```yaml # YAML 配置 cors: allowed-origins: http://localhost:5173,http://localhost:3000 ``` ```java // CorsConfig.java @Value("${cors.allowed-origins:*}") private String[] allowedOrigins; // 自动按逗号分割成数组 ``` --- ## **敏感配置处理** ### **使用环境变量占位符** ```yaml # application.yml - 支持环境变量的安全配置 spring: datasource: url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:database} username: ${DB_USERNAME:root} password: ${DB_PASSWORD:} # 空字符串作为默认值 app: jwt: secret: ${JWT_SECRET:default-dev-secret-change-in-production} # 语法说明: # ${ENV_VAR} - 必须存在的环境变量 # ${ENV_VAR:default} - 带默认值的环境变量 # ${ENV_VAR:} - 默认空字符串 ``` ### **部署时设置环境变量** ```bash # ==================== Linux/macOS ==================== # 方式1: 导出环境变量 export DB_HOST=prod-db.example.com export DB_USERNAME=prod_user export DB_PASSWORD=super_secret_password export JWT_SECRET=your-production-jwt-secret-key export SPRING_PROFILES_ACTIVE=prod java -jar app.jar # 方式2: 一行命令 DB_HOST=prod-db.example.com DB_PASSWORD=xxx java -jar app.jar # 方式3: 使用 .env 文件(配合启动脚本) source .env && java -jar app.jar # ==================== Docker ==================== # 方式1: docker run -e docker run -d \ -e SPRING_PROFILES_ACTIVE=prod \ -e DB_HOST=db.example.com \ -e DB_PASSWORD=secret \ -e JWT_SECRET=jwt-secret \ app:latest # 方式2: docker-compose.yml services: app: image: app:latest environment: - SPRING_PROFILES_ACTIVE=prod - DB_HOST=db - DB_PASSWORD=${DB_PASSWORD} # 从宿主机环境变量读取 env_file: - .env.prod # 或从文件读取 # ==================== Kubernetes ==================== # ConfigMap (非敏感配置) apiVersion: v1 kind: ConfigMap metadata: name: app-config data: SPRING_PROFILES_ACTIVE: "prod" DB_HOST: "db.example.com" # Secret (敏感配置) apiVersion: v1 kind: Secret metadata: name: app-secrets type: Opaque data: DB_PASSWORD: c3VwZXJfc2VjcmV0 # base64 编码 JWT_SECRET: and0LXNlY3JldA== ``` --- ## **完整使用示例** ### **在代码中使用配置** ```java @RestController @RequestMapping("/demo") public class DemoController { // 方式1: 注入整个配置类 @Autowired private AppProperties appProperties; // 方式2: 使用 @Value 注入单个值 @Value("${app.name}") private String appName; @GetMapping("/config") public Map getConfig() { Map config = new HashMap<>(); // 使用配置类 config.put("appName", appProperties.getName()); config.put("version", appProperties.getVersion()); config.put("debug", appProperties.isDebug()); // 嵌套配置 config.put("jwtExpiration", appProperties.getJwt().getExpiration()); config.put("maxFileSize", appProperties.getFile().getMaxSize()); config.put("maxPasswordRetry", appProperties.getUser().getMaxPasswordRetry()); return config; } } ``` ### **启动项目的不同方式** ```properties # 开发环境(默认) mvn spring-boot:run # 指定环境启动 mvn spring-boot:run -Dspring-boot.run.profiles=dev mvn spring-boot:run -Dspring-boot.run.profiles=test mvn spring-boot:run -Dspring-boot.run.profiles=prod # JAR 包运行 java -jar app.jar # 使用默认环境 java -jar app.jar --spring.profiles.active=prod # 指定生产环境 java -Dspring.profiles.active=prod -jar app.jar # JVM 参数方式 # 带环境变量 SPRING_PROFILES_ACTIVE=prod \ DB_HOST=db.example.com \ DB_PASSWORD=secret \ java -jar app.jar ``` --- ## **总结** ```text ┌─────────────────────────────────────────────────────────────────┐ │ 配置管理要点 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 1. 分层配置 │ │ └── application.yml 放通用配置和默认值 │ │ └── application-{env}.yml 放环境特定配置 │ │ │ │ 2. 敏感信息 │ │ └── 【禁止】硬编码在配置文件中 │ │ └── 【必须】使用环境变量占位符 ${VAR:default} │ │ └── 【推荐】生产环境使用配置中心(Nacos/Apollo) │ │ │ │ 3. 安全检查清单 │ │ └── 生产环境关闭 knife4j.enable │ │ └── 生产环境关闭 app.debug │ │ └── 生产环境 JWT Secret 必须通过环境变量配置 │ │ └── 生产环境 CORS 严格限制域名 │ │ └── 生产环境关闭 SQL 日志输出 │ │ │ │ 4. 配置验证 │ │ └── 使用 @Validated 验证必填配置 │ │ └── 启动时检查关键配置是否正确 │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- **项目分区导航**:⬅️ [[03-优雅配置管理方案|03-优雅配置管理方案]] | 04-多环境配置详解 | ➡️ [[2-Learning/05-项目/05-最佳实践/01-MVC分层与项目规范/05-ZwwwSpringBootBaseTemplate工程模板|05-ZwwwSpringBootBaseTemplate工程模板]]