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

启用SpringDocs时OpenTelemetry Spring Boot Starter的ParameterNameDiscoverer Bean冲突问题求助

启用SpringDocs时OpenTelemetry Spring Boot Starter的ParameterNameDiscoverer Bean冲突问题求助

大家好,我最近在给Spring Boot应用配置通过OTLP导出日志、追踪和指标,用了官方的OpenTelemetry Spring Boot Starter,按照文档要求导入了对应的BOM和依赖,大部分配置看起来都没问题,但启动应用时遇到了Bean冲突的错误,具体情况如下:

启动报错日志

16:44:39.629 [restartedMain] WARN  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'otelInstrumentationWithSpanAspect' defined in class path resource [io/opentelemetry/instrumentation/spring/autoconfigure/instrumentation/annotations/InstrumentationAnnotationsAutoConfiguration.class]: Unsatisfied dependency expressed through method 'otelInstrumentationWithSpanAspect' parameter 1: No qualifying bean of type 'org.springframework.core.ParameterNameDiscoverer' available: expected single matching bean but found 2: parameterNameDiscoverer,localSpringDocParameterNameDiscoverer

16:44:39.635 [restartedMain] INFO  i.o.sdk.logs.SdkLoggerProvider - Calling shutdown() multiple times.

16:44:39.636 [restartedMain] INFO  i.o.e.internal.grpc.GrpcExporter - Calling shutdown() multiple times.

16:44:39.636 [restartedMain] INFO  i.o.sdk.metrics.SdkMeterProvider - Multiple close calls

16:44:39.636 [restartedMain] INFO  i.o.e.internal.grpc.GrpcExporter - Calling shutdown() multiple times.

16:44:39.636 [restartedMain] INFO  i.o.sdk.trace.SdkTracerProvider - Calling shutdown() multiple times.

16:44:39.636 [restartedMain] INFO  i.o.e.internal.grpc.GrpcExporter - Calling shutdown() multiple times.

16:44:39.637 [restartedMain] INFO  o.a.catalina.core.StandardService - Stopping service [Tomcat]

16:44:39.649 [restartedMain] INFO  o.s.b.a.l.ConditionEvaluationReportLogger -

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.

16:44:39.657 [restartedMain] ERROR o.s.b.d.LoggingFailureAnalysisReporter -

***************************

APPLICATION FAILED TO START

***************************

Description:

Parameter 1 of method otelInstrumentationWithSpanAspect in io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.annotations.InstrumentationAnnotationsAutoConfiguration required a single bean, but 2 were found:

- parameterNameDiscoverer: defined by method 'parameterNameDiscoverer' in class path resource [io/opentelemetry/instrumentation/spring/autoconfigure/instrumentation/annotations/InstrumentationAnnotationsAutoConfiguration.class]

- localSpringDocParameterNameDiscoverer: defined by method 'localSpringDocParameterNameDiscoverer' in class path resource [org/springdoc/core/configuration/SpringDocConfiguration.class]

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

问题分析

从报错信息能明确看出,OpenTelemetry的InstrumentationAnnotationsAutoConfiguration和SpringDoc的SpringDocConfiguration各自定义了一个ParameterNameDiscoverer类型的Bean,而OpenTelemetry的otelInstrumentationWithSpanAspect方法在注入时需要唯一的该类型Bean,因此触发了依赖注入冲突。

可行的解决办法

我整理了几个实用的解决方案,大家可以根据自己的需求选择:

  • 方案一:标记其中一个Bean为@Primary
    自定义一个配置类,将其中一个ParameterNameDiscoverer Bean标记为优先使用的Primary Bean。比如如果想优先使用OpenTelemetry自带的Bean,可以这么写:

    @Configuration
    public class PrimaryParameterNameDiscovererConfig {
        @Primary
        @Bean
        public ParameterNameDiscoverer primaryParameterNameDiscoverer(
                @Qualifier("parameterNameDiscoverer") ParameterNameDiscoverer otelParameterNameDiscoverer) {
            return otelParameterNameDiscoverer;
        }
    }
    

    如果想优先使用SpringDoc的Bean,只需要把@Qualifier的值改成localSpringDocParameterNameDiscoverer即可。

  • 方案二:通过@Qualifier指定注入的Bean
    我们可以自定义配置类,覆盖OpenTelemetry的otelInstrumentationWithSpanAspect Bean的创建逻辑,明确指定要使用的ParameterNameDiscoverer:

    @Configuration
    @AutoConfigureBefore(InstrumentationAnnotationsAutoConfiguration.class)
    public class OtelAspectOverrideConfig {
        @Bean
        public OtelInstrumentationWithSpanAspect otelInstrumentationWithSpanAspect(
                Tracer tracer,
                @Qualifier("parameterNameDiscoverer") ParameterNameDiscoverer parameterNameDiscoverer,
                @Value("${otel.instrumentation.spring.annotations.enabled:true}") boolean enabled) {
            return new OtelInstrumentationWithSpanAspect(tracer, parameterNameDiscoverer, enabled);
        }
    }
    

    这个方案更明确,直接指定OpenTelemetry使用自己定义的ParameterNameDiscoverer,避免冲突。

  • 方案三:排除冲突的自动配置类(不推荐)
    如果确认不需要其中某一方的ParameterNameDiscoverer,可以在@SpringBootApplication注解中排除对应的自动配置类,比如排除SpringDoc的配置:

    @SpringBootApplication(exclude = SpringDocConfiguration.class)
    

    但这个方法风险较高,可能会导致SpringDoc的功能异常,除非你确定不需要SpringDoc的相关功能,否则不建议使用。

总结

优先推荐方案一或方案二,这两个方法都能在不影响原有功能的前提下解决Bean冲突问题,方案一更简洁,方案二更精准。

备注:内容来源于stack exchange,提问作者vkourt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 12:04:33