实体类使用@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 

总结

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

相关文章

  • SpringBoot基于Redis实现生成全局唯一ID的方法

    SpringBoot基于Redis实现生成全局唯一ID的方法

    在项目中生成全局唯一ID有很多好处,生成全局唯一ID有助于提高系统的可用性、数据的完整性和安全性,同时也方便数据的管理和分析,所以本文给大家介绍了SpringBoot基于Redis实现生成全局唯一ID的方法,文中有详细的代码讲解,需要的朋友可以参考下
    2023-12-12
  • 如何动态修改JavaBean中注解的参数值

    如何动态修改JavaBean中注解的参数值

    这篇文章主要介绍了如何动态修改JavaBean中注解的参数值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Java中的自旋锁spinlock详解

    Java中的自旋锁spinlock详解

    这篇文章主要介绍了Java中的自旋锁spinlock详解,自旋锁就是循环尝试获取锁,不会放弃CPU时间片,减伤cup上下文切换,缺点是循环会消耗cpu,需要的朋友可以参考下
    2024-01-01
  • Java基于Tcp的基础聊天功能实例

    Java基于Tcp的基础聊天功能实例

    这篇文章主要介绍了Java基于Tcp的基础聊天功能,结合实例形式分析了java基于tcp协议的数据传输实现聊天功能相关操作技巧,需要的朋友可以参考下
    2020-01-01
  • Java中SpringCloud的五大组件详解

    Java中SpringCloud的五大组件详解

    这篇文章主要介绍了Java中SpringCloud的五大组件详解,Spring cloud是一个基于Spring Boot实现的服务治理工具包,在微服务架构中用于管理和协调服务,需要的朋友可以参考下
    2023-07-07
  • springBoot 打war包 程序包com.sun.istack.internal不存在的问题及解决方案

    springBoot 打war包 程序包com.sun.istack.internal不存在的问题及解决方案

    这篇文章主要介绍了springBoot 打war包 程序包com.sun.istack.internal不存在的问题及解决方案,亲测试过可以,需要的朋友可以参考下
    2018-07-07
  • SpringBoot实战项目之谷歌浏览器全屏效果实现

    SpringBoot实战项目之谷歌浏览器全屏效果实现

    这篇文章主要介绍了通过 Java SpringBoot来实现谷歌浏览器的全屏效果,希望页面展示时可以实现全屏效果以提高用户体验。感兴趣的小伙伴跟着小编往下看吧
    2021-09-09
  • java整合微信支付功能详细示例

    java整合微信支付功能详细示例

    这篇文章主要给大家介绍了关于java整合微信支付功能的相关资料,支付是一个复杂且测试起来需要的配置特别复杂的模块,文中给出了详细的示例代码,需要的朋友可以参考下
    2023-07-07
  • IDEA中创建properties配置文件

    IDEA中创建properties配置文件

    我们在j2ee当中,连接数据库的时候经常会用到properties配置文件,本文主要介绍了IDEA中创建properties配置文件,具有一定的参考价值, 感兴趣的可以了解一下
    2024-04-04
  • java面试LruCache 和 LinkedHashMap及算法实现

    java面试LruCache 和 LinkedHashMap及算法实现

    这篇文章主要为大家介绍了java面试LruCache 和 LinkedHashMap及算法实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02

最新评论