多环境配置详解

多环境配置

配置文件优先级

配置文件优先级-20cf86f9

激活环境的方式

# ==================== 方式对比 ====================

# 方式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

配置类与 YAML 的对应关系

AppProperties 对应关系

# 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
┌──────────────────────────────────────────────────────────────────┐
│                     命名转换规则                                  │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  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 配置
cors:
  allowed-origins: http://localhost:5173,http://localhost:3000
// CorsConfig.java
@Value("${cors.allowed-origins:*}")
private String[] allowedOrigins;  // 自动按逗号分割成数组

敏感配置处理

使用环境变量占位符

# 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:}         - 默认空字符串

部署时设置环境变量

# ==================== 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==

完整使用示例

在代码中使用配置

@RestController
@RequestMapping("/demo")
public class DemoController {

    // 方式1: 注入整个配置类
    @Autowired
    private AppProperties appProperties;

    // 方式2: 使用 @Value 注入单个值
    @Value("${app.name}")
    private String appName;

    @GetMapping("/config")
    public Map<String, Object> getConfig() {
        Map<String, Object> 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;
    }
}

启动项目的不同方式

# 开发环境(默认)
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

总结

┌─────────────────────────────────────────────────────────────────┐
│                         配置管理要点                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. 分层配置                                                     │
│     └── application.yml 放通用配置和默认值                        │
│     └── application-{env}.yml 放环境特定配置                     │
│                                                                 │
│  2. 敏感信息                                                     │
│     └── 【禁止】硬编码在配置文件中                                │
│     └── 【必须】使用环境变量占位符 ${VAR:default}                 │
│     └── 【推荐】生产环境使用配置中心(Nacos/Apollo)              │
│                                                                 │
│  3. 安全检查清单                                                  │
│     └── 生产环境关闭 knife4j.enable                              │
│     └── 生产环境关闭 app.debug                                   │
│     └── 生产环境 JWT Secret 必须通过环境变量配置                  │
│     └── 生产环境 CORS 严格限制域名                                │
│     └── 生产环境关闭 SQL 日志输出                                 │
│                                                                 │
│  4. 配置验证                                                     │
│     └── 使用 @Validated 验证必填配置                             │
│     └── 启动时检查关键配置是否正确                                │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

项目分区导航:⬅️ 03-优雅配置管理方案 | 04-多环境配置详解 | ➡️ 05-ZwwwSpringBootBaseTemplate工程模板