文章目录

  • 1. 前言
  • 2. 场景
  • 3. 解释
  • 4. 解决方法
  • 5. 思考

1. 前言

  1. 这里只是列出,可能需要补一下的知识点:
  2. 具体的yml文件字符串、List、Map的书写方式并使用@ConfigurationProperties注入配置类.
  3. 使用@Builder导致的无法创建无参构造方法

2. 场景

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

    1. 该类必须是bean对象,即加了@Component注解。
    2. 该类必须得有set方法,即加@Setter注解。
  2. 偶然一次发现,当在该类加上@Builder注解,会直接导致无法属性注入。

  3. 重现
    正常情况下:

    @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 {@AutowireddemoFailedTest demoFailedTest;@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println(demoFailedTest);}
    }
    failed:test:user-name: failedTestage: 19demo-person:name: personsex: 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. 解决方法

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

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

5. 思考

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

    1. builder创建对象方式很优雅,写的很简洁。
    2. 有没有一种可能,就是需求就是不想对外提供默认无参构造方法,或者全参构造方法,不想别人随便就可以new 对象出来了。
  2. 如果要满足第二点原因,显然现在是无法做到的,因为spring使用set方法注入,得有无参构造方法先创建对象,但是我们又不想提供无参构造方法,这不是矛盾吗?
  3. 再额外补充一个问题:如果这个Person类,我只想通过配置文件注入之后,永远不被修改,固然不能提供set方法,但是因为spring使用set方法注入属性,这不也是矛盾吗?
  4. 此时,突然脑子里面肯定会出现一个想法:为什么只会有set方法注入,不应该吧,set都可以,应该也可以有构造函数注入吧。
  5. 是的,下一篇文章:
    spring的构造函数注入属性@ConstructorBinding

实体类使用@Builder,导致@ConfigurationProperties注入属性失败相关推荐

  1. springboot @ConfigurationProperties注入属性流程

    一.编写实例,只要加上ConfigurationProperties注解,就会从当前springboot的Environment中读取配置属笥.Environment包括bootStrap,appli ...

  2. java 复制实体类_Java实现两个实体类相同属性的复制/拷贝

    在两个实体类里,有相同的属性,有不同的属性,相同名称的属性类型还可能不同,如何实现相同属性的拷贝/复制呢? 实体类 代码清单1:Neo4jNode.java package com.graph.dom ...

  3. 减少到处衍生的实体类

    这里的实体类更倾向于数据传输对象(既DTO).无论是编码风格采用 事务脚本 还是 领域模型,我们都会遇到各种各样的数据传输对象,尤其是传统事务脚本三层架构的编码中,更会遇到各类实体对象,一般来说,这些 ...

  4. 浅谈三层架构中的实体类(C#)

    最近因为三层架构中的实体类,引发了不少小问题,下面列举一下,谈谈自己的感想. 本文所指的实体类仅限于三层中的实体类,即数据库表的映射. 一.为什么要用实体类? |  使程序简洁易懂,便于维护. |  ...

  5. XML文件与实体类的互相转换

    1. 通常程序的配置信息都保存在程序或者网站的专门的配置文件中(App.config/web.config).但是现在为了演示XML序列化和反序列化,将配置信息保存在一个XML文件(config.xm ...

  6. IOC操作Bean管理XML方式(有参构造注入属性)

    IOC操作Bean管理XML方式 目录 有参构造注入属性 (1)步骤(创建类,定义属性,创建属性对应的有参构造方法): (2)步骤:在Spring 的xml配置文件中进行配置 (3)步骤:进行测试 结 ...

  7. 自动生成三层结构代码(2)--生成实体类

    版权所有:基础软件.作者邮箱:sun.j.l.studio@gmail.com.本文首发于 http://www.cnblogs.com/FoundationSoft.文章转载请保持此版权信息并注明出 ...

  8. 2017-4-20实体类,数据访问类.字符串攻击.防攻击

    程序分三层:界面层.业务逻辑层.数据访问层 这里主要操作的是数据访问层,数据访问层又分为: 1.实体类 2.数据访问类 存放位置:APP_Code文件中 一.实体类 最简单的封装 把数据库的表名变成类 ...

  9. C#之三十七 实体类

    视频课:  C#程序设计与宿舍管理系统实战 3.1      使用实体类构建三层结构概述 在上一章中的三层架构中,我们使用DataSet来进行数据的传递,但在OOP的开发中,有很大的局限性: 1.   ...

最新文章

  1. 做销售如何跟单,逼单!共20招!(转)
  2. java fork join原理_细说Fork/Join框架
  3. 使用 邮箱配置 激活码 用于 用户注册激活
  4. Linux系统篇-文件系统虚拟文件系统
  5. Thrift Java Servers Compared
  6. Android基于mAppWidget实现手绘地图(三)--环境搭建
  7. [NOIP2016]愤怒的小鸟 状态压缩dp
  8. Mybatis逆向工程自动生成代码文件
  9. oracle中使用kill,WINDOWS和LINUX服务器级别的KILLORACLE进行方法
  10. onvif协议之抓图
  11. iOS开发之使用Runtime给Model类赋值
  12. 管理新语:如果经验有用,大家都去养老院招人了
  13. 人人都是 DBA(II)SQL Server 元数据 (转)
  14. windows linux jdk8 jdk11下载
  15. 使用adb命令获取手机ip地址
  16. Android gatekeeper的原理介绍和代码导读
  17. 小鹏汽车领投 这家车规级MEMS激光雷达公司完成数亿元Pre-C轮融资
  18. 阿里云服务器与本地不能复制粘贴
  19. 【论文】Learning RoI Transformer for Oriented Object Detection in Aerial Images
  20. target找不到*.xml和*.properties文件 报错:FileNotFoundException

热门文章

  1. 怎么查看各进程分别占用多少服务器内存?
  2. 关于SQL中的ASSERTION(某单位想举行一个小型的联谊会……)
  3. 【ML】英雄联盟对局胜负预测任务
  4. 云计算大会超融合论坛分享
  5. android设备 应用场景,友盟2015年Q2、Q3季度中国移动互联网趋势报告:用数据构建用户使用场景...
  6. android 自动化 微信,C#手把手教你玩微信自动化
  7. python-random模块
  8. 转:明茨伯格:管理者的“选“、“育“、“评”
  9. 基于SSM职业测评系统
  10. P2657 [SCOI2009] windy 数(数位DP)