You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus中如何编程获取Keycloak Dev Services自动分配的运行端口

你注入的quarkus.keycloak.devservices.port是预配置固定端口用的配置项,只有当你手动给这个参数赋值的时候才会存在。当使用系统自动分配端口时,这个配置项未被赋值,所以注入时会抛出配置不存在的异常,你可以用以下两种方法获取实际运行端口:


方法1:从自动生成的认证服务地址提取端口

Keycloak Dev Service启动完成后,会自动将实际可访问的服务地址写入配置项quarkus.oidc.auth-server-url,该配置项在自动分配端口场景下也会存在,你可以注入该配置后从中提取端口:

import org.eclipse.microprofile.config.inject.ConfigProperty;
import java.net.URL;
import java.net.MalformedURLException;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class KeycloakConfig {
    @ConfigProperty(name = "quarkus.oidc.auth-server-url")
    String authServerUrl;

    public int getDevServicePort() {
        try {
            URL url = new URL(authServerUrl);
            return url.getPort();
        } catch (MalformedURLException e) {
            throw new RuntimeException("解析Keycloak服务地址失败", e);
        }
    }
}

如果你的项目未引入OIDC扩展,也可以注入quarkus.keycloak.devservices.auth-server-url配置项,取值和上述配置完全一致。


方法2:监听DevService启动事件直接获取端口

你可以监听Quarkus提供的DevServicesStartedEvent事件,在事件回调中直接从Keycloak容器实例中获取映射的宿主机端口,这种方式不需要解析URL,更直接:

import io.quarkus.devservices.common.DevServicesStartedEvent;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import org.testcontainers.containers.KeycloakContainer;
import io.quarkus.arc.profile.IfBuildProfile;

// 限制仅在开发/测试模式加载该Bean,避免生产模式报错
@IfBuildProfile(profile = {"dev", "test"})
@ApplicationScoped
public class KeycloakPortHolder {
    private Integer devServicePort;

    public void onDevServicesReady(@Observes DevServicesStartedEvent event) {
        for (var service : event.getDevServices()) {
            if (service.getContainer() instanceof KeycloakContainer kcContainer) {
                // 8080为Keycloak容器内部默认监听端口
                devServicePort = kcContainer.getMappedPort(8080);
                break;
            }
        }
    }

    public Integer getDevServicePort() {
        return devServicePort;
    }
}

注意事项

  • 方法2仅在开发模式和测试模式下生效,生产模式不会启动Dev Service,因此给Bean加上了profile限制,避免生产环境加载报错。
  • 如果你需要同时兼容手动指定端口和自动分配端口的场景,可以给注入的配置项加上默认值,结合两种方法做兼容处理。

内容的提问来源于stack exchange,提问作者Sebastian S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:39:00