Java【问题 05】yml配置文件boolean一直为false问题分析解决

简介: Java【问题 05】yml配置文件boolean一直为false问题分析解决

1.问题说明

application.yml配置文件里的布尔值获取后一直为false

2.bug复现

2.1 yml配置

# 测试
test-config:
  is: true
  open: true
  isOpen: true

2.2 配置类

@Data
@Component
@ConfigurationProperties(TestConfiguration.PREFIX)
public class TestConfiguration {
    public static final String PREFIX = "test-config";
    /**
     * 参数key为is的boolean值
     */
    public boolean is;
    /**
     * 参数key为open的boolean值
     */
    public boolean open;
    /**
     * 参数key为isOpen的boolean值
     */
    public boolean isOpen;
}

2.3 测试类

@Component
@Slf4j
public class TestManager {
    @Autowired
    private TestConfiguration testConfiguration;
    @PostConstruct
    public void init() {
        boolean is = testConfiguration.is;
        boolean open = testConfiguration.open;
        boolean isOpen = testConfiguration.isOpen;
        log.info("is[{}];open[{}];isOpen[{}]", is, open, isOpen);
    }
}

2.4 结果输出

17:07:25.804 [restartedMain] INFO  x.x.x.x.x.TestManager - [init,28] - is[true];open[true];isOpen[false]

3.源码分析

3.1 @Data

阿里巴巴的《Java开发手册》有这么一条规则:【强制】POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误。

反例:定义为基本数据类型 Boolean isDeleted 的属性,它的方法也是 isDeleted(),框架在反向解析的时候,“误以为”对应的属性名称是 deleted,导致属性获取不到,进而抛出异常。

由于TestConfiguration类使用了lombok@Data这里贴出编译结果【为了简洁这里删除了重写的hashCode()和equals()及相关的方法】:

@Component
@ConfigurationProperties("test-config")
public class TestConfiguration {
    public static final String PREFIX = "test-config";
    public boolean is;
    public boolean open;
    public boolean isOpen;
    public TestConfiguration() {
    }
    public boolean isIs() {
        return this.is;
    }
    public boolean isOpen() {
        return this.open;
    }
    public void setIs(final boolean is) {
        this.is = is;
    }
    public void setOpen(final boolean open) {
        this.open = open;
    }
    public String toString() {
        return "TestConfiguration(is=" + this.isIs() + ", open=" + this.isOpen() + ", isOpen=" + this.isOpen() + ")";
    }
}

查看源码后我们可以发现以下问题:

  1. open的get方法是isOpen()。
  2. isOpen属性根本就没有被赋值。
  3. isOpen的属性值等于open的值。

这里修改open的值进行验证:

# 测试
test-config:
  is: true
  open: false
  isOpen: true

17:34:46.783 [restartedMain] INFO  c.x.d.g.m.TestManager - [init,28] - is[true];open[false];isOpen[false]

3.2 Generate Getters and Setters

神奇的是,自动生成的get和set方法也只给is和open进行了赋值和获取:

public boolean isIs() {
        return is;
    }
    public void setIs(boolean is) {
        this.is = is;
    }
    public boolean isOpen() {
        return open;
    }
    public void setOpen(boolean open) {
        this.open = open;
    }

直接测试,isOpen的值果不其然就是false

4.问题解决

4.1 修改参数名称

不使用isXXX这样的参数名称。

4.2 添加Getter和Setter方法

public boolean isIsOpen() {
        return isOpen;
    }
    public void setIsOpen(boolean isOpen) {
        this.isOpen = isOpen;
    }

重新测试:

# 测试
test-config:
  is: false
  open: false
  isOpen: true

结果:

17:46:29.591 [restartedMain] INFO  c.x.d.g.m.TestManager - [init,28] - is[false];open[false];isOpen[true]
目录
相关文章
|
4天前
|
Java 程序员
Java 一个 Scanner.nextInt 造成的奇怪问题及分析解决过程
Java 一个 Scanner.nextInt 造成的奇怪问题及分析解决过程
|
1月前
|
监控 Java
Java中的内存泄漏分析与排查技巧
Java中的内存泄漏分析与排查技巧
|
4天前
|
JSON 前端开发 JavaScript
JSON parse error: Cannot deserialize value of type `java.lang.Integer` from Boolean value
这篇文章讨论了前端Vue应用向后端Spring Boot服务传输数据时发生的类型不匹配问题,即后端期望接收的字段类型为`int`,而前端实际传输的类型为`Boolean`,导致无法反序列化的问题,并提供了问题的诊断和解决方案。
JSON parse error: Cannot deserialize value of type `java.lang.Integer` from Boolean value
|
5天前
|
存储 Java 编译器
刷完一千道java笔试题的常见题目分析
这篇文章是关于刷完一千道Java笔试题后的常见题目分析,涵盖了Java基础知识点,如标识符命名规则、抽象类与接口的区别、String类的equals方法、try-catch-finally块的执行逻辑、类与实例方法的区别、this与super关键字的用法、面向对象的基本概念、重写与重载的原则等,并建议结合JVM内存结构图加深理解。
刷完一千道java笔试题的常见题目分析
|
14天前
|
安全 Java
Java RMI技术详解与案例分析
在实际的银行系统中,当然还需要考虑安全性、事务性、持久性以及错误处理等多方面的因素,RMI的网络通信也需要在安全的网络环境下进行,以防止数据泄露或被篡改。你在应用中是怎么使用 RMI 的,欢迎关注威哥爱编程,一起交流一下哈。
132 4
|
20天前
|
存储 SQL Java
(七)全面剖析Java并发编程之线程变量副本ThreadLocal原理分析
在之前的文章:彻底理解Java并发编程之Synchronized关键字实现原理剖析中我们曾初次谈到线程安全问题引发的"三要素":多线程、共享资源/临界资源、非原子性操作,简而言之:在同一时刻,多条线程同时对临界资源进行非原子性操作则有可能产生线程安全问题。
|
25天前
|
监控 算法 Java
|
3天前
|
算法 安全 Java
深入解析Java多线程:源码级别的分析与实践
深入解析Java多线程:源码级别的分析与实践
|
5天前
|
Java 测试技术 Spring
Java SpringBoot 加载 yml 配置文件中字典项
Java SpringBoot 加载 yml 配置文件中字典项
10 0
|
8天前
|
监控 Java
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
17 0

热门文章

最新文章