在Quarkus中如何基于方法创建Micrometer动态Gauge?
问题根源分析
你的问题核心是依赖注入时机不匹配:Quarkus遵循Jakarta EE规范,Bean的构造函数会优先执行,之后才会处理@Inject注解标记的字段注入。所以在你原来的构造函数中,service字段还未完成注入,处于null状态,基于它创建的两个Gauge自然无法正常生成指标。
解决方案
有两种可靠的修复方式,推荐优先使用第一种:
方式1:统一使用构造函数注入(Quarkus官方推荐)
把PdfConverterService也作为构造函数参数,由Quarkus直接注入,确保构造函数执行时所有依赖都已初始化完成:
private final PdfConverterService service; private final MeterRegistry registry; private final List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7); // 构造函数注入所有依赖 public PdfConverterResource(MeterRegistry registry, PdfConverterService service) { this.registry = registry; this.service = service; this.registry.gauge("foo.bar", 42); this.registry.gauge("foo.foo.bar", Tags.of("A", "B"), this.list, List::size); // 此时service已完成初始化,可正常创建Gauge this.registry.gauge("foo.baz", Tags.of("A", "B"), this.service, s -> s.getConversionDiskUsage().doubleValue()); Gauge.builder("conversion.volume.usage", this.service, PdfConverterService::getConversionDiskUsage) .description("Shows the disk usage of the attached volume used for the PDF conversion") .register(this.registry); }
方式2:使用@PostConstruct延后Gauge初始化
如果不想调整构造函数注入方式,可以用@PostConstruct标记初始化方法,该方法会在所有字段注入完成后执行:
@Inject PdfConverterService service; @Inject MeterRegistry registry; private final List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7); public PdfConverterResource() {} @PostConstruct void initMetrics() { this.registry.gauge("foo.bar", 42); this.registry.gauge("foo.foo.bar", Tags.of("A", "B"), this.list, List::size); this.registry.gauge("foo.baz", Tags.of("A", "B"), this.service, s -> s.getConversionDiskUsage().doubleValue()); Gauge.builder("conversion.volume.usage", this.service, PdfConverterService::getConversionDiskUsage) .description("Shows the disk usage of the attached volume used for the PDF conversion") .register(this.registry); }
额外注意事项
- 确保
PdfConverterService被Quarkus识别为Bean(比如添加@ApplicationScoped或其他Scope注解),否则无法被正常注入。 - Gauge依赖目标对象的引用存活,容器管理的Bean(如你的
PdfConverterService)不会被轻易GC回收,无需担心引用失效问题。
内容的提问来源于stack exchange,提问作者eerriicc
相关产品推荐
相关产品推荐

