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

如何为Quarkus实现自定义Dev Service并在DevUI中展示?

自定义Quarkus Dev Service的最佳实践

要在Quarkus开发模式中复用你的容器逻辑并作为Dev Service展示在DevUI中,核心是实现Quarkus的DevServicesProvider接口,同时通过DevUI扩展添加状态展示。以下是具体步骤:

1. 抽离容器复用逻辑

先把测试代码里的容器创建、启停逻辑抽成工具类,让测试和Dev Service共享代码,避免重复实现:

import org.testcontainers.containers.GenericContainer;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.wait.strategy.Wait;
import java.io.File;
import java.util.Map;

public class ExternalServiceContainerUtil {
    private static GenericContainer<?> container;

    public static Map<String, String> startContainer() {
        // 复用你原有的镜像与容器配置
        ImageFromDockerfile image = new ImageFromDockerfile()
                .withDockerfile(new File("src/main/docker/your-service.Dockerfile"));
        
        container = new GenericContainer<>(image)
                .withExposedPorts(8080)
                .waitingFor(Wait.forHttp("/health").forStatusCode(200));
        
        container.start();

        // 返回应用需要的配置属性,比如服务地址
        return Map.of(
                "external-service.base-url", 
                String.format("http://%s:%d", container.getHost(), container.getMappedPort(8080))
        );
    }

    public static void stopContainer() {
        if (container != null && container.isRunning()) {
            container.stop();
        }
    }
}

2. 实现DevServicesProvider接口

这个接口是Quarkus自定义Dev Service的核心,负责在开发模式启动时创建、管理容器:

import io.quarkus.deployment.dev.devservices.DevServicesContext;
import io.quarkus.deployment.dev.devservices.DevServicesProvider;
import io.quarkus.deployment.dev.devservices.DevServicesResult;
import jakarta.inject.Singleton;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import java.util.Map;

@Singleton
public class ExternalServiceDevServicesProvider implements DevServicesProvider {

    @Override
    public DevServicesResult start(DevServicesContext context) {
        // 通过配置开关控制是否启用该Dev Service
        Config config = ConfigProvider.getConfig();
        boolean enabled = config.getOptionalValue("quarkus.devservices.external-service.enabled", Boolean.class)
                .orElse(true);
        
        if (!enabled) {
            return null;
        }

        // 启动容器并获取配置属性
        Map<String, String> serviceProperties = ExternalServiceContainerUtil.startContainer();

        // 定义服务停止回调
        DevServicesResult.RunningDevService runningService = new DevServicesResult.RunningDevService(
                "external-service",
                ExternalServiceContainerUtil::stopContainer,
                serviceProperties
        );

        return DevServicesResult.builder()
                .addRunningService(runningService)
                .build();
    }

    @Override
    public boolean supports(String name) {
        return "external-service".equals(name);
    }

    @Override
    public int priority() {
        return 50; // 优先级数值,按需调整,避免与其他Dev Service冲突
    }
}

3. 添加DevUI展示

要让你的Dev Service出现在Quarkus的DevUI中,创建一个DevUI扩展类:

import io.quarkus.devui.page.PageTitle;
import io.quarkus.devui.runtime.component.DevUIComponent;
import jakarta.inject.Inject;
import org.eclipse.microprofile.config.Config;

@DevUIComponent(title = "External Service", category = "External Services")
public class ExternalServiceDevUI {

    @Inject
    Config config;

    @PageTitle("Service Status")
    public String getServiceStatus() {
        String serviceUrl = config.getOptionalValue("external-service.base-url", String.class)
                .orElse("Not running");
        return String.format("External Service is running at: %s", serviceUrl);
    }

    // 可扩展添加更多信息,比如容器ID、日志查看链接等
}

4. 复用测试逻辑

你的QuarkusTestResourceLifecycleManager可以直接复用工具类,保持测试与开发环境的一致性:

import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import java.util.Map;

public class ExternalServiceTestResource implements QuarkusTestResourceLifecycleManager {

    @Override
    public Map<String, String> start() {
        return ExternalServiceContainerUtil.startContainer();
    }

    @Override
    public void stop() {
        ExternalServiceContainerUtil.stopContainer();
    }
}

相关API文档说明

Quarkus官方文档的Extending Quarkus章节下,有针对DevServicesProvider接口和DevUI扩展的详细说明,核心内容包括:

  • Dev Service的生命周期管理逻辑
  • 配置属性的传递方式
  • DevUI组件的注册与自定义展示

内容的提问来源于stack exchange,提问作者Jakob Graf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:43:12