同一套代碼部署到開發、測試、生產環境,數據庫連接、Redis 地址、日誌級別、第三方 API Key 等配置各不相同。Spring Profile 提供「同一配置文件、多套環境隔離、啟動時動態切換」的優雅方案。
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 開發環境 -->
<beans profile="dev">
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="jdbcUrl" value="jdbc:mysql://dev-db:3306/myapp"/>
<property name="username" value="dev_user"/>
<property name="password" value="dev_pwd"/>
</bean>
</beans>
<!-- 測試環境 -->
<beans profile="test">
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="jdbcUrl" value="jdbc:mysql://test-db:3306/myapp"/>
<property name="username" value="test_user"/>
<property name="password" value="test_pwd"/>
</bean>
</beans>
<!-- 生產環境 -->
<beans profile="prod">
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="jdbcUrl" value="jdbc:mysql://prod-db:3306/myapp"/>
<property name="username" value="${prod.db.user}"/>
<property name="password" value="${prod.db.pwd}"/>
</bean>
</beans>
</beans>
# application.yml
spring:
profiles:
active: dev # 默認激活
---
spring:
config:
activate:
on-profile: dev
datasource:
url: jdbc:mysql://dev-db:3306/myapp
username: dev_user
password: dev_pwd
---
spring:
config:
activate:
on-profile: test
datasource:
url: jdbc:mysql://test-db:3306/myapp
username: test_user
password: test_pwd
---
spring:
config:
activate:
on-profile: prod
datasource:
url: jdbc:mysql://prod-db:3306/myapp
username: ${PROD_DB_USER}
password: ${PROD_DB_PWD}
# application-dev.properties
datasource.url=jdbc:mysql://dev-db:3306/myapp
datasource.username=dev_user
datasource.password=dev_pwd
# application-prod.properties
datasource.url=jdbc:mysql://prod-db:3306/myapp
datasource.username=prod_user
datasource.password=prod_pwd
# 主文件 application.properties
spring.profiles.active=dev
# 或引入共用配置
spring.profiles.include=common,redis,mq
| 方式 | 適用場景 | 示例 |
|---|---|---|
| JVM 參數 | 所有部署方式通用 | -Dspring.profiles.active=prod |
| 環境變量 | Docker/K8s/雲原生 | SPRING_PROFILES_ACTIVE=prod |
| 命令行參數 | Jar 包直接運行 | java -jar app.jar --spring.profiles.active=prod |
| Servlet 容器上下文參數 | 傳統 War 部署 Tomcat | web.xml 配置 spring.profiles.active context-param |
| 代碼編程式設置 | 測試/特殊邏輯 | SpringApplication.setAdditionalProfiles("prod") |
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
# 激活多個 profile
spring.profiles.active=dev,redis,swagger
# 在 profile 中包含其他 profile(Spring Boot 2.4+)
spring:
config:
activate:
on-profile: dev
profiles:
include: common,redis # 自動激活 common 和 redis
@Configuration
@Profile("dev") // 僅 dev 環境註冊
public class DevConfig {
@Bean
public DataSource dataSource() { return new EmbeddedDatabaseBuilder().build(); }
}
@Configuration
@Profile("prod")
public class ProdConfig {
@Bean
public DataSource dataSource() { return new HikariDataSource(...); }
}
@Bean
@ConditionalOnProperty(name = "feature.new-api", havingValue = "true")
public NewApiClient newApiClient() { return new NewApiClient(); }
application-common.yml,spring.profiles.include 引入dev/test/staging/prod,避免隨意命名application-local.yml(.gitignore 忽略),spring.profiles.active=localSpring Profile 是「配置與代碼分離、環境隔離」的基石。掌握 XML/YAML/Properties 多種配置姿勢、5 種激活方式、組合與條件化技巧,能讓應用從開發到生產「一次構建,到處運行」,構建雲原生就緒的配置管理體系。