关于 azure-appconfiguration-java
用于 Java 应用连接 Azure App Configuration 的客户端库,供需要集中管理应用配置的开发者使用。它支持设置、标签、功能标志和快照,并提供同步与异步客户端。
主要功能
- 01创建、读取、更新和删除配置项
- 02按键模式和标签筛选配置
- 03管理功能标志与密钥引用
- 04创建并管理不可变快照
- 05支持同步和异步客户端
适用场景
- 01按环境标签读取应用配置
- 02为发布保存配置快照
- 03管理功能逐步发布标志
- 04使用 ETag 避免并发覆盖
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill azure-appconfiguration-java安装后在 Claude Code 中输入/azure-appconfiguration-java确认已加载。
详细介绍
Azure App Configuration SDK for Java
Azure App Configuration 的客户端库,这是一项用于集中管理应用程序配置的托管服务。
安装
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-appconfiguration</artifactId>
<version>1.8.0</version>
</dependency>
或者使用 Azure SDK BOM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-sdk-bom</artifactId>
<version>{bom_version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-appconfiguration</artifactId>
</dependency>
</dependencies>
先决条件
- Azure App Configuration 存储
- 连接字符串或 Entra ID 凭据
环境变量
AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://<store>.azconfig.io;Id=<id>;Secret=<secret>
AZURE_APPCONFIG_ENDPOINT=https://<store>.azconfig.io
创建客户端
使用连接字符串
import com.azure.data.appconfiguration.ConfigurationClient;
import com.azure.data.appconfiguration.ConfigurationClientBuilder;
ConfigurationClient configClient = new ConfigurationClientBuilder()
.connectionString(System.getenv("AZURE_APPCONFIG_CONNECTION_STRING"))
.buildClient();
异步客户端
import com.azure.data.appconfiguration.ConfigurationAsyncClient;
ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
.connectionString(connectionString)
.buildAsyncClient();
使用 Entra ID(推荐)
import com.azure.identity.DefaultAzureCredentialBuilder;
ConfigurationClient configClient = new ConfigurationClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(System.getenv("AZURE_APPCONFIG_ENDPOINT"))
.buildClient();
核心概念
| 概念 | 说明 |
|---|---|
| 配置项 | 带有可选标签的键值对 |
| 标签 | 用于区分配置项的维度(例如环境) |
| 功能标志 | 用于功能管理的特殊配置项 |
| 密钥引用 | 指向 Key Vault 密钥的配置项 |
| 快照 | 配置项在某个时间点的不可变视图 |
配置项操作
创建配置项(Add)
仅在配置项不存在时创建:
import com.azure.data.appconfiguration.models.ConfigurationSetting;
ConfigurationSetting setting = configClient.addConfigurationSetting(
"app/database/connection",
"Production",
"Server=prod.db.com;Database=myapp"
);
创建或更新配置项(Set)
创建或覆盖:
ConfigurationSetting setting = configClient.setConfigurationSetting(
"app/cache/enabled",
"Production",
"true"
);
获取配置项
ConfigurationSetting setting = configClient.getConfigurationSetting(
"app/database/connection",
"Production"
);
System.out.println("Setting retrieved; value omitted from logs");
System.out.println("Content-Type: " + setting.getContentType());
System.out.println("Last Modified: " + setting.getLastModified());
条件获取(如果已更改)
import com.azure.core.http.rest.Response;
import com.azure.core.util.Context;
Response<ConfigurationSetting> response = configClient.getConfigurationSettingWithResponse(
setting, // Setting with ETag
null, // Accept datetime
true, // ifChanged - only fetch if modified
Context.NONE
);
if (response.getStatusCode() == 304) {
System.out.println("Setting not modified");
} else {
ConfigurationSetting updated = response.getValue();
}
更新配置项
ConfigurationSetting updated = configClient.setConfigurationSetting(
"app/cache/enabled",
"Production",
"false"
);
条件更新(如果未更改)
// Only update if ETag matches (no concurrent modifications)
Response<ConfigurationSetting> response = configClient.setConfigurationSettingWithResponse(
setting, // Setting with current ETag
true, // ifUnchanged
Context.NONE
);
删除配置项
ConfigurationSetting deleted = configClient.deleteConfigurationSetting(
"app/cache/enabled",
"Production"
);
条件删除
Response<ConfigurationSetting> response = configClient.deleteConfigurationSettingWithResponse(
setting, // Setting with ETag
true, // ifUnchanged
Context.NONE
);
列出和筛选配置项
按键模式列出
import com.azure.data.appconfiguration.models.SettingSelector;
import com.azure.core.http.rest.PagedIterable;
SettingSelector selector = new SettingSelector()
.setKeyFilter("app/*");
PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);
for (ConfigurationSetting s : settings) {
System.out.println(s.getKey());
}
按标签列出
SettingSelector selector = new SettingSelector()
.setKeyFilter("*")
.setLabelFilter("Production");
PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);
按多个键列出
SettingSelector selector = new SettingSelector()
.setKeyFilter("app/database/*,app/cache/*");
PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);
列出修订版本
SettingSelector selector = new SettingSelector()
.setKeyFilter("app/database/connection");
PagedIterable<ConfigurationSetting> revisions = configClient.listRevisions(selector);
for (ConfigurationSetting revision : revisions) {
System.out.println("Modified: " + revision.getLastModified());
}
功能标志
创建功能标志
import com.azure.data.appconfiguration.models.FeatureFlagConfigurationSetting;
import com.azure.data.appconfiguration.models.FeatureFlagFilter;
import java.util.Arrays;
FeatureFlagFilter percentageFilter = new FeatureFlagFilter("Microsoft.Percentage")
.addParameter("Value", 50);
FeatureFlagConfigurationSetting featureFlag = new FeatureFlagConfigurationSetting("beta-feature", true)
.setDescription("Beta feature rollout")
.setClientFilters(Arrays.asList(percentageFilter));
FeatureFlagConfigurationSetting created = (FeatureFlagConfigurationSetting)
configClient.addConfigurationSetting(featureFlag);
获取功能标志
FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting)
configClient.getConfigurationSetting(featureFlag);
System.out.println("Feature: " + flag.getFeatureId());
System.out.println("Enabled: " + flag.isEnabled());
System.out.println("Filters: " + flag.getClientFilters());
更新功能标志
featureFlag.setEnabled(false);
FeatureFlagConfigurationSetting updated = (FeatureFlagConfigurationSetting)
configClient.setConfigurationSetting(featureFlag);
密钥引用
创建密钥引用
import com.azure.data.appconfiguration.models.SecretReferenceConfigurationSetting;
SecretReferenceConfigurationSetting secretRef = new SecretReferenceConfigurationSetting(
"app/secrets/api-key",
"https://myvault.vault.azure.net/secrets/api-key"
);
SecretReferenceConfigurationSetting created = (SecretReferenceConfigurationSetting)
configClient.addConfigurationSetting(secretRef);
获取密钥引用
SecretReferenceConfigurationSetting ref = (SecretReferenceConfigurationSetting)
configClient.getConfigurationSetting(secretRef);
System.out.println("Secret URI: " + ref.getSecretId());
只读配置项
设置为只读
ConfigurationSetting readOnly = configClient.setReadOnly(
"app/critical/setting",
"Production",
true
);
清除只读状态
ConfigurationSetting writable = configClient.setReadOnly(
"app/critical/setting",
"Production",
false
);
快照
创建快照
import com.azure.data.appconfiguration.models.ConfigurationSnapshot;
import com.azure.data.appconfiguration.models.ConfigurationSettingsFilter;
import com.azure.core.util.polling.SyncPoller;
import com.azure.core.util.polling.PollOperationDetails;
List<ConfigurationSettingsFilter> filters = new ArrayList<>();
filters.add(new ConfigurationSettingsFilter("app/*"));
SyncPoller<PollOperationDetails, ConfigurationSnapshot> poller = configClient.beginCreateSnapshot(
"release-v1.0",
new ConfigurationSnapshot(filters),
Context.NONE
);
poller.setPollInterval(Duration.ofSeconds(10));
poller.waitForCompletion();
ConfigurationSnapshot snapshot = poller.getFinalResult();
System.out.println("Snapshot: " + snapshot.getName() + ", Status: " + snapshot.getStatus());
获取快照
ConfigurationSnapshot snapshot = configClient.getSnapshot("release-v1.0");
System.out.println("Created: " + snapshot.getCreatedAt());
System.out.println("Items: " + snapshot.getItemCount());
列出快照中的配置项
PagedIterable<ConfigurationSetting> settings =
configClient.listConfigurationSettingsForSnapshot("release-v1.0");
for (ConfigurationSetting setting : settings) {
System.out.println(setting.getKey());
}
归档快照
ConfigurationSnapshot archived = configClient.archiveSnapshot("release-v1.0");
System.out.println("Status: " + archived.getStatus()); // archived
恢复快照
ConfigurationSnapshot recovered = configClient.recoverSnapshot("release-v1.0");
System.out.println("Status: " + recovered.getStatus()); // ready
列出所有快照
import com.azure.data.appconfiguration.models.SnapshotSelector;
SnapshotSelector selector = new SnapshotSelector().setNameFilter("release-*");
PagedIterable<ConfigurationSnapshot> snapshots = configClient.listSnapshots(selector);
for (ConfigurationSnapshot snap : snapshots) {
System.out.println(snap.getName() + " - " + snap.getStatus());
}
标签
列出标签
import com.azure.data.appconfiguration.models.SettingLabelSelector;
configClient.listLabels(new SettingLabelSelector().setNameFilter("*"))
.forEach(label -> System.out.println("Label: " + label.getName()));
异步操作
ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
.connectionString(connectionString)
.buildAsyncClient();
// Async list with reactive streams
asyncClient.listConfigurationSettings(new SettingSelector().setLabelFilter("Production"))
.subscribe(
setting -> System.out.println(setting.getKey()),
error -> System.err.println("Error: " + error.getMessage()),
() -> System.out.println("Completed")
);
错误处理
import com.azure.core.exception.HttpResponseException;
try {
configClient.getConfigurationSetting("nonexistent", null);
} catch (HttpResponseException e) {
if (e.getResponse().getStatusCode() == 404) {
System.err.println("Setting not found");
} else {
System.err.println("Error: " + e.getMessage());
}
}
最佳实践
- 使用标签 — 按环境(开发、预发布、生产)区分配置
- 使用快照 — 为发布创建不可变快照
- 功能标志 — 用于渐进式发布和 A/B 测试
- 密钥引用 — 在 Key Vault 中存储敏感值
- 条件请求 — 使用 ETag 实现乐观并发控制
- 只读保护 — 锁定关键的生产配置项
- 使用 Entra ID — 优先于连接字符串
- 异步客户端 — 用于高吞吐量场景
参考链接
适用场景
此技能适用于执行概述中描述的工作流或操作。
限制
- 仅当任务明确符合上述范围时,才使用此技能。
- 不要将输出视为环境特定验证、测试或专家审查的替代品。
- 如果缺少必要的输入、权限、安全边界或成功标准,请停止并请求澄清。
依赖项版本和代码片段是历史示例,并不代表已编译或当前版本的声明。请包含 Azure Identity 和必需的 Java 导入项,根据所选 BOM 验证方法签名,并限制响应式任务和生命周期。标签是组织维度,不是安全边界。功能标志不是授权控制;设置存储不会评估客户端筛选条件。Key Vault 引用需要单独授权解析,且不包含机密值。允许的主体可以解除只读设置的锁定;快照并非无限期的灾难恢复保障。限制生产环境写入操作,不要打印配置值或连接字符串。
评论
支持 Markdown