配置
ACE Framework 使用 TOML 作为配置文件格式,支持多环境覆盖合并。配置系统在应用启动时完成初始化,此后通过 @Value 注解或 AppConfig API 在任意 Bean 中读取。
配置文件格式
配置文件使用 TOML 子集,支持字符串、整数、布尔、表(section)和占位符插值。不支持 TOML 的数组表([[table]])语法。
完整示例:application.toml
[ace]
env = "local" # 默认激活环境,可被 CLI --env 参数覆盖
[server]
host = "0.0.0.0"
port = 8080
read-timeout-ms = 30000
write-timeout-ms = 30000
[jwt]
secret = "change-me-in-prod"
expires-ms = 3600000 # 1 小时
[datasource]
url = "sqlite://./data/app.db"
pool-min = 2
pool-max = 10
[openapi]
enabled = true
title = "Task API"
version = "1.0.0"
path = "/api-docs"
[logging]
level = "info" # trace / debug / info / warn / error
format = "json" # json / simple / text
output = "stdout"
[base]
url = "http://localhost:${server.port}" # 占位符引用同文件其他 key配置文件加载顺序
ACE 在启动时按以下顺序依次加载并叠加合并配置,后加载的文件覆盖同名 key:
config/application.toml ← 基础配置(必须存在)
config/application-{env}.toml ← 当前环境覆盖(可选,不存在则跳过)合并规则:key 级别覆盖,同一 section 下后者的 key 覆盖前者,不存在的 key 保留前者的值。
环境切换
有两种方式指定当前运行环境:
方式一:CLI 参数(优先级最高)
# 运行时加载 application.toml + application-prod.toml
target/release/bin/task_api --env=prod方式二:application.toml 中声明默认环境
[ace]
env = "dev"推荐实践
在 application.toml 中设置 ace.env = "local",将本地开发配置放在 application-local.toml。CI/CD 流水线通过 --env=prod 覆盖,避免生产配置进入代码仓库。
仓颉无环境变量 API
仓颉标准库目前没有稳定的 getenv 支持,因此 ACE 的环境标识走 --env CLI 参数路线,而非 APP_ENV 环境变量。不要在配置系统中依赖 System.getenv()。
多环境配置文件列表
| 文件 | 用途 |
|---|---|
config/application.toml | 所有环境共用的基础配置,必须存在 |
config/application-local.toml | 本地开发,通常不提交到 Git |
config/application-dev.toml | 开发服务器 |
config/application-test.toml | 自动化测试环境(CI) |
config/application-prod.toml | 生产环境 |
@Value 注入配置项
在任意被 ACE 容器管理的 Bean(@Service、@Controller 等)中,使用 @Value["key"] 注入配置值:
package task_api.service
import ace_framework.*
@Service
class JwtService {
// 注入配置,提供默认值
@Value["jwt.secret"]
var secret: String = "default-secret"
@Value["jwt.expires-ms"]
var expiresMs: Int64 = 3600000
@Value["server.port"]
var port: Int64 = 8080
@Value["openapi.enabled"]
var openapiEnabled: Bool = false
func sign(payload: String): String {
// 使用 secret 生成 JWT ...
return ""
}
}@Value 支持的类型
| 类型 | 示例 |
|---|---|
String | @Value["server.host"] var host: String = "localhost" |
Int64 | @Value["server.port"] var port: Int64 = 8080 |
Bool | @Value["openapi.enabled"] var enabled: Bool = false |
Float64 | @Value["cache.ttl-ratio"] var ratio: Float64 = 0.8 |
注入时机
@Value 在 Bean 实例化后、@PostConstruct 方法执行前完成注入。不要在构造函数中读取 @Value 字段——此时注入尚未发生,字段仍为声明时的初始值。
手动读取:AppConfig API
当需要在非 Bean 上下文(如工厂函数、初始化脚本)中读取配置时,使用 AppConfig 单例:
import ace_framework.*
let config = AppConfig.getInstance()
// 读取字符串,不存在时返回默认值
let host: String = config.getOr("server.host", "127.0.0.1")
// 读取整数
let port: Int64 = config.getInt("server.port", 8080)
// 读取布尔
let debug: Bool = config.getBool("logging.debug", false)
// 读取 Float64
let ratio: Float64 = config.getFloat("cache.ratio", 0.75)
// 读取原始字符串(不存在时返回 None)
let raw: Option<String> = config.get("custom.key")AppConfig API 速查
| 方法 | 返回类型 | 说明 |
|---|---|---|
get(key) | Option<String> | 读取原始字符串,不存在返回 None |
getOr(key, default) | String | 读取字符串,不存在返回默认值 |
getInt(key, default) | Int64 | 解析整数,解析失败返回默认值 |
getBool(key, default) | Bool | 解析布尔("true"/"1" 为真),失败返回默认值 |
getFloat(key, default) | Float64 | 解析浮点数,失败返回默认值 |
占位符插值
配置值中可用 ${key} 引用同一配置树中的其他 key,支持默认值语法 ${key:defaultValue}:
[base]
url = "http://localhost:${server.port}"
[cors]
allowed-origin = "${base.url:http://localhost:8080}"
[openapi]
servers = "${base.url}/api"插值在配置加载完成、多文件合并后统一展开,因此可以引用来自环境覆盖文件的 key。
循环引用检测
若占位符引用形成循环(如 a = "${b}" 且 b = "${a}"),ACE 在启动时会抛出 ConfigCycleError 并终止程序,不会进入死循环。
示例:按环境覆盖数据库连接
config/application.toml(基础):
[datasource]
url = "sqlite://./data/dev.db"
pool-min = 1
pool-max = 5config/application-prod.toml(生产覆盖):
[datasource]
url = "postgres://user:pass@db-host:5432/proddb"
pool-min = 5
pool-max = 50以 --env=prod 启动后,datasource.url 和 pool-max 使用生产值,其余 key 保持基础配置不变。