Spring Boot Sping Boot 构造函数中出现意外错误

syqv5f0l  于 2023-03-02  发布在  Spring
关注(0)|答案(3)|浏览(116)

我写了一个示例程序如下。

@Configuration
public class MyclassName{

    private final List<String> tableIds;

    public MyclassName(
        List<String> tableIds) {
        this.tableIds = tableIds;
    }
}

运行时,我得到下面的错误。

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in MyclassName required a single bean, but 4 were found:
    - spring.sleuth.baggage-keys: defined by method 'baggageKeys' in class path resource [org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfiguration.class]
    - spring.sleuth.local-keys: defined by method 'localKeys' in class path resource [org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfiguration.class]
    - spring.sleuth.propagation-keys: defined by method 'propagationKeys' in class path resource [org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfiguration.class]
    - spring.sleuth.log.slf4j.whitelisted-mdc-keys: defined by method 'whiteListedMDCKeys' in class path resource [org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfiguration.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

Process finished with exit code 0

我们使用sleuth进行跟踪,所以pom.xml也有依赖关系。但这是一个非常基本的例子,为什么我会得到这个错误。有人能帮助吗?

j91ykkif

j91ykkif1#

MyclassName对于spring框架是已知的。
所以spring会尝试使用构造函数来创建MyclassName的一个示例:

public MyclassName(List<String> tableIds)

Parameter 0 of constructor in MyclassNameList<String> tableIds
Spring试图为这个参数提供一个值,但是它找到了4,而不是只有一个可用的值。所以Spring不够聪明,不应该选择一个代替你。
4个可用值由Sleuth提供,并在TraceBaggageConfiguration.class中声明,如下所示:

@Bean(BAGGAGE_KEYS)
@ConfigurationProperties(BAGGAGE_KEYS)
List<String> baggageKeys() {...}

@Bean(LOCAL_KEYS)
@ConfigurationProperties(LOCAL_KEYS)
List<String> localKeys()  {...}

@Bean(PROPAGATION_KEYS)
@ConfigurationProperties(PROPAGATION_KEYS)
List<String> propagationKeys()  {...}

@Bean(WHITELISTED_MDC_KEYS)
@ConfigurationProperties(WHITELISTED_MDC_KEYS)
List<String> whiteListedMDCKeys()  {...}

为了解决这种犹豫不决的问题,您需要通过使用唯一标识符来告诉Spring您真正想要在构造函数中注入哪个List<String>
首先限定(给予一个id)预期的bean

@Bean("myExpectedTableIds")
List<String> myTableIdsProcucerMethod()

然后使用org.springframework.beans.factory.annotation.Qualifier注解告诉Spring您真正想要的bean:

public MyclassName(@Qualifier("myExpectedTableIds") List<String> tableIds)
baubqpgj

baubqpgj2#

public MyclassName(
        List<String> tableIds) {
        this.tableIds = tableIds;
    }

这意味着你的MyclassNames,作为Spring中的一个Configuration bean,需要注入一个类型为List<String>的bean,碰巧sluethTraceBaggageConfiguration类定义了一些类型为List<String>的bean:

@org.springframework.context.annotation.Bean({"spring.sleuth.baggage-keys"})
    @org.springframework.boot.context.properties.ConfigurationProperties("spring.sleuth.baggage-keys")
    java.util.List<java.lang.String> baggageKeys() { /* compiled code */ }

    @org.springframework.context.annotation.Bean({"spring.sleuth.local-keys"})
    @org.springframework.boot.context.properties.ConfigurationProperties("spring.sleuth.local-keys")
    java.util.List<java.lang.String> localKeys() { /* compiled code */ }

    @org.springframework.context.annotation.Bean({"spring.sleuth.propagation-keys"})
    @org.springframework.boot.context.properties.ConfigurationProperties("spring.sleuth.propagation-keys")
    java.util.List<java.lang.String> propagationKeys() { /* compiled code */ }

因此spring报告了一个错误,不知道要注入哪个bean。您可能需要使用Qualifier来指定要注入的bean。或者,您是否定义了对应的bean,该bean散列了需要注入的List<String>类型?MyclassName中的List<String> tableIds是什么?您需要如下定义Bean

public MyclassNamesss(
            @Qualifier("test") List<String> tableIds) {
        this.tableIds = tableIds;
    }

    @Bean("test")
    public List<String> myString() {
        return new ArrayList<>();
    }

或者,您可以使用,在本例中,tableId将为null

public MyclassName(
            @Autowired(required = false) List<String> tableIds) {
        this.tableIds = tableIds;
    }
5ssjco0h

5ssjco0h3#

不管怎样,因为我发现这篇文章在寻找相同的错误消息,所以我在Sping Boot 中使用Lombok的@RequiredArgsConstructor注入List<String>

@Component
    @RequiredArgsConstructor
    @ConfigurationProperties(prefix = "some-prefix")
    public static class SomeProperties {
        @Getter
        private final List<String> patterns;
    }

并通过手动初始化列表修复了该问题:

@Component
    @ConfigurationProperties(prefix = "some-prefix")
    public static class SomeProperties {
        @Getter
        private final List<String> patterns = new ArrayList<>();
    }

然后用Spring属性正确地填充该列表。

相关问题