SpringBoot的config bean使用中的坑

文章讲述了在SpringBoot项目中,使用Lombok的@Builder注解和@Value进行配置注入时遇到的构造函数依赖问题。解决办法包括移除构造函数或添加无参构造函数,并理解@Builder与@NoArgsConstructor的冲突。
摘要由CSDN通过智能技术生成
@Data
@Component
@Builder
public class KnowledgeInfoConfig {
    @Value("${knowledge.connectTimeout:500}")
    private Integer connectTimeout;

    @Value("${knowledge.socketTimeout:500}")
    private Integer socketTimeout;

    @Value("${knowledge.connectionRequestTimeout:500}")
    private Integer connectionRequestTimeout;

    @Value("${knowledge.requestTimeout:500}")
    private Integer requestTimeout;

    @Value("${knowledge.knowledgeInfoUrl}")
    private String knowledgeInfoUrl;

}

上述的代码在项目启动时,会出现:Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.Integer' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

报错信息表明 Spring 在实例化 KnowledgeInfoConfig 类时出现了问题,因为无法找到类型为 java.lang.Integer 的 bean。

这种情况通常是因为 Spring 尝试注入 KnowledgeInfoConfig 类的构造函数参数时,发现了 Integer 类型的参数,但无法找到匹配的 bean。

在您的 KnowledgeInfoConfig 类中,您使用了 @Value 注解来注入属性值,这通常不需要构造函数注入。但是,报错信息表明 Spring 正在尝试通过构造函数注入属性值。

  1. 移除构造函数: 如果您不需要使用构造函数注入属性值,可以尝试移除 KnowledgeInfoConfig 类的构造函数。Spring 应该能够通过默认的无参构造函数实例化该类,并使用 @Value 注解来注入属性值。

  2. 明确声明构造函数: 如果您确实需要一个构造函数来处理其他逻辑,可以在 KnowledgeInfoConfig 类中显式声明一个无参构造函数,并确保所有属性都由 @Value 注解注入,而不是通过构造函数。

当您在类上添加 @Builder 注解时,Lombok 会为该类生成一个包含所有非静态字段的静态内部类,并为每个字段生成一个相应的设置方法。这样您就可以使用这个生成的建造者模式来创建对象,而不必编写繁琐的构造函数。

然而,在 Spring 中,当您的类需要被实例化为一个 bean,并且其中的属性需要通过 @Value 注解来注入时,@Builder 注解会产生一些影响。具体来说,Lombok 生成的建造者模式并不会为生成的建造者类添加 @Value 注解所需的构造函数。

因此,在您的情况下,当 Spring 尝试实例化 KnowledgeInfoConfig 类时,它需要找到一个合适的构造函数来满足 @Value 注解所需的依赖注入。但是由于 @Builder 注解生成的建造者类没有合适的构造函数,因此 Spring 无法找到满足依赖注入需求的构造函数,最终导致了报错。

解决这个问题的方法之一是在类上添加一个无参构造函数,并确保所有的属性都可以通过 @Value 注解注入。或者,您可以考虑在使用 @Builder 注解的类中手动创建一个建造者模式,以满足 Spring 对依赖注入的要求。

修改后在类注解上添加如下注解即可:

@NoArgsConstructor
@AllArgsConstructor

只加无参构造注解也会出现编译问题:

无法将类 com.xiaoju.uemc.waymo.config.KnowledgeInfoConfig中的构造器 KnowledgeInfoConfig应用到给定类型;

原因:

具体来说,@NoArgsConstructor 注解会生成一个无参构造函数,而 @Builder 注解会生成一个具有参数的构造函数。当您同时在一个类上使用这两个注解时,它们可能会产生冲突,导致编译错误。

@Data
@Component
@Builder
public class KnowledgeInfoConfig {
    @Value("${knowledge.connectTimeout:500}")
    private Integer connectTimeout;
}

编译后:

public class KnowledgeInfoConfig {
    private Integer connectTimeout;

    // 构造器(通常为私有,但这里只是示例)
    private KnowledgeInfoConfig(Integer connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    // 静态内部建造者类
    public static class KnowledgeInfoConfigBuilder {
        private Integer connectTimeout;

        // setter 方法,用于设置属性值
        public KnowledgeInfoConfigBuilder connectTimeout(Integer connectTimeout) {
            this.connectTimeout = connectTimeout;
            return this;
        }

        // build 方法,用于构建对象实例
        public KnowledgeInfoConfig build() {
            return new KnowledgeInfoConfig(connectTimeout);
        }
    }
}

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值