实体类使用@Builder,导致@ConfigurationProperties注入属性失败问题

 更新时间:2023年12月15日 14:57:33   作者:搏·梦  
这篇文章主要介绍了实体类使用@Builder,导致@ConfigurationProperties注入属性失败问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1. 前言

这里只是列出,可能需要补一下的知识点:

具体的yml文件字符串、List、Map的书写方式并使用@ConfigurationProperties注入配置类.

使用@Builder导致的无法创建无参构造方法

2. 场景

@ConfigurationProperties注入属性,有两个很重要的条件:

  • 该类必须是bean对象,即加了@Component注解。
  • 该类必须得有set方法,即加@Setter注解。

偶然一次发现,当在该类加上@Builder注解,会直接导致无法属性注入。

重现

正常情况下:

@ToString
@Setter
@Component
@ConfigurationProperties(prefix = "failed.test")
public class demoFailedTest {

    private String username;
    private int age;
    private demoPerson demoPerson;
}

@Setter
@ToString
public class demoPerson {
    private String name;
    private String sex;
}
@Component("demoFailedTestRunner")
public class demoRunner implements ApplicationRunner {

    @Autowired
    demoFailedTest demoFailedTest;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println(demoFailedTest);
    }
}

failed:
  test:
    user-name: failedTest
    age: 19
    demo-person:
      name: person
      sex: boy

异常情况:当在demoPerson类上加上@Builder注解:

@Builder
@Setter
@ToString
public class demoPerson {
    private String name;
    private String sex;
}

一开始都惊了,本来就是符合条件的,demoPerson类上面有set方法,不应该注入不进来。

3. 解释

1.上面两张图片有个输出有个很细微的差异,一开始我也没有看出来,后来才反应过来了:

第一个:

demoFailedTest(username=failedTest, age=19, demoPerson=demoPerson(name=person, sex=boy))

第二个:

demoFailedTest(username=failedTest, age=19, demoPerson=null)

注: demoPerson类上 加了@ToString

讲道理,第二个报错不应该是:

demoFailedTest(username=failedTest, age=19, demoPerson=demoPerson(name=null, sex=null))

这样子才是真正注入不进来属性的结果。

那么现在直接 demoPerson=null 代表 该demoPerson根本没有被创建对象!!!

2.后来详细去了解了@Builder注解的作用:

详细:使用@Builder导致的无法创建无参构造方法

简单说一下:就是如果你只是使用了@Builder则会导致 该类的没有无参构造函数,会有全参构造函数

3.重点:spring属性注入的时候,为什么要有set方法,显示它是使用set方法注入的,它又不能直接使用对象.set方法(),想必是使用了反射,那就必须得有对象吧,可得 spring肯定是先反射创建对象,是的,没错,spring默认是使用无参构造函数创建对象,再调用反射的set方法。

4.因此,如果加上@Builder注解,会没有无参构造函数方法,当然是没有办法创建对象了,因此才会出现 demoPerson=null的结果

4. 解决方法

具体@Builder的解决方法,上面链接里面有三种,我演示其中一种,即在该类上加上@AllArgsConstructor@NoArgsConstructor。

@ToString
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class demoPerson {
    private String name;
    private String sex;

}

5. 思考

根据第四大点的解决方法,加上@AllArgsConstructor、@NoArgsConstructor即可,但有没有想过为什么要用@Builder方法

原因:

  • builder创建对象方式很优雅,写的很简洁。
  • 有没有一种可能,就是需求就是不想对外提供默认无参构造方法,或者全参构造方法,不想别人随便就可以new 对象出来了。

如果要满足第二点原因,显然现在是无法做到的,因为spring使用set方法注入,得有无参构造方法先创建对象,但是我们又不想提供无参构造方法,这不是矛盾吗?

再额外补充一个问题:如果这个Person类,我只想通过配置文件注入之后,永远不被修改,固然不能提供set方法,但是因为spring使用set方法注入属性,这不也是矛盾吗?

此时,突然脑子里面肯定会出现一个想法:为什么只会有set方法注入,不应该吧,set都可以,应该也可以有构造函数注入吧。

是的,下一篇文章:

spring的构造函数注入属性@ConstructorBinding 

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring IoC容器知识点详解

    Spring IoC容器知识点详解

    在本篇文章里小编给各位整理的是关于Spring IoC容器的相关知识点内容,有需要的朋友们可以学习下。
    2019-09-09
  • Java中的SimpleDateFormat使用详解

    Java中的SimpleDateFormat使用详解

    SimpleDateFormat 是一个以国别敏感的方式格式化和分析数据的具体类。这篇文章主要介绍了Java中的SimpleDateFormat使用详解,需要的朋友可以参考下
    2017-03-03
  • Java类和对象全面解析

    Java类和对象全面解析

    本文介绍了Java面向对象编程的核心概念,文章通过具体代码示例,帮助读者理解Java面向对象编程的基本原理和实践方法,感兴趣的朋友跟随小编一起看看吧
    2026-05-05
  • Java初始化块及执行过程解析

    Java初始化块及执行过程解析

    这篇文章主要介绍了Java初始化块及执行过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Java中ArrayList和SubList的坑面试题

    Java中ArrayList和SubList的坑面试题

    集合是Java开发日常开发中经常会使用到的,下面这篇文章主要给大家介绍了关于Java中ArrayList和SubList的坑面试题,需要的朋友可以参考下
    2022-05-05
  • Spring表达式语言SpEL用法详解

    Spring表达式语言SpEL用法详解

    这篇文章主要介绍了spring表达式语言SpEL用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • 使用JAVA获取nacos配置信息出现null,获取不到的解决

    使用JAVA获取nacos配置信息出现null,获取不到的解决

    文章讨论了在使用Java获取Nacos配置信息时遇到的问题,特别是调用ConfigService获取配置时出现null的情况,作者尝试了多种解决方法,最终发现更换jar包版本(1.*)解决了问题,作者分享了个人经验,希望能对大家有所帮助
    2025-12-12
  • RestTemplate报错400 Bad Request的解决方案

    RestTemplate报错400 Bad Request的解决方案

    在使用Spring Boot时,若直接通过@Autowired注入RestTemplate可能会遇到400BadRequest错误,原因在于Spring Boot官方文档指出,由于RestTemplate实例通常需要在使用前进行定制,因此Spring Boot不会自动配置单个RestTemplate Bean
    2024-11-11
  • SpringBoot创建多模块项目的全过程记录

    SpringBoot创建多模块项目的全过程记录

    这篇文章主要给大家介绍了关于SpringBoot创建多模块项目的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • JSP页面无法识别EL表达式问题解决方案

    JSP页面无法识别EL表达式问题解决方案

    这篇文章主要介绍了JSP页面无法识别EL表达式问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07

最新评论