不可不知!SpringBoot 3.4 中 @DefaultValue 注解的妙用与实战

开发 前端
@DefaultValue​ 注解是 Spring Boot 3.4 中非常实用的功能,它使得我们在属性绑定时能够为缺失的属性提供默认值,减少了因缺失配置而产生的异常和错误。

在 Spring Boot 3.4 中,@DefaultValue 注解为我们提供了更加灵活的配置方式,尤其是在配置属性绑定时。在实际开发中,配置文件的属性绑定通常会通过两种方式来实现,分别是 @ConfigurationProperties 和 @Value。尽管两者都能够完成绑定任务,但通常推荐使用 @ConfigurationProperties,因为它提供了更高的结构化和类型安全性。

@ConfigurationProperties VS @Value

@ConfigurationProperties 为配置文件属性绑定提供了一个更清晰且类型安全的方式。它将配置文件中的属性映射到 Java 类的字段上,增强了代码的可读性和可维护性。而 @Value 虽然也能够完成绑定任务,但通常只适用于简单的属性,并且在处理复杂绑定时,它缺乏类型安全的保障。使用 @Value 时,还可能需要额外的自定义类型转换器。

因此,在 Spring Boot 项目中,为了提升代码的可维护性和避免潜在的错误,通常推荐使用 @ConfigurationProperties 来绑定配置属性。通过这种方式,代码结构更加清晰,同时也能避免运行时错误。

使用构造函数进行属性绑定

通常情况下,@ConfigurationProperties 会通过 setter 方法来进行属性绑定。然而,Spring Boot 还支持使用构造函数来进行属性绑定,提供了更为灵活的绑定方式。以下示例演示了如何使用构造函数进行绑定:

package com.icoderoad.config;


import org.springframework.boot.context.properties.ConfigurationProperties;


@ConfigurationProperties(prefix = "pack.app")
public class PackApp {
    private String title;
    private String version;
    private Integer sno;


    public PackApp(String title, String version, Integer sno) {
        this.title = title;
        this.version = version;
        this.sno = sno;
    }


    // getters, setters
}

在这个示例中,PackApp 类将会使用构造函数进行属性绑定。

处理多个构造函数

当配置类中存在多个构造函数时,Spring Boot 默认会使用 setter 方法进行绑定。如果希望指定使用某一个构造函数进行绑定,可以使用 @ConstructorBinding 注解:

package com.icoderoad.config;


import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.boot.context.properties.ConfigurationProperties;


@ConfigurationProperties(prefix = "pack.app")
public class PackApp {
    private String title;
    private String version;
    private Integer sno;


    @ConstructorBinding
    public PackApp(String title, String version) {
        this.title = title;
        this.version = version;
    }
}

这种情况下,Spring Boot 会使用带有两个参数的构造函数进行属性绑定。

默认构造函数与私有构造函数

如果配置类只有一个有参构造函数,Spring Boot 会默认使用这个构造函数进行绑定。如果不希望使用该构造函数进行绑定,可以将其设置为 private 或者使用 @Autowired 注解:

package com.icoderoad.config;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;


@ConfigurationProperties(prefix = "pack.app")
public class PackApp {
    private String title;
    private String version;
    private Integer sno;


    @Autowired
    public PackApp(MyBean bean) {
        // 初始化代码
    }
}

通过这种方式,Spring Boot 会使用 setter 方法来完成属性绑定。

@DefaultValue 注解的使用

当使用构造函数绑定时,如果某些属性在配置文件中没有找到对应的值,@DefaultValue 注解可以为这些属性设置默认值。

假设配置文件如下:

pack:
  app:
    title: xxxx.xxxx
    version: 1.0.0

若配置文件中没有定义 pack.app.sno 属性,默认情况下 sno 会被赋值为 null。但如果我们希望在没有配置该属性时使用默认值,可以使用 @DefaultValue 注解:

package com.icoderoad.config;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.beans.factory.annotation.Value;


@ConfigurationProperties(prefix = "pack.app")
public class PackApp {
    private String title;
    private String version;


    @DefaultValue("888")
    private Integer sno;


    public PackApp(String title, String version, Integer sno) {
        this.title = title;
        this.version = version;
        this.sno = sno;
    }


    // getters, setters
}

运行时,如果 pack.app.sno 没有在配置文件中提供值,sno 会自动使用默认值 888。

嵌套属性的默认值

如果你的配置类包含嵌套属性,也可以使用 @DefaultValue 为这些嵌套属性设置默认值。例如:

package com.icoderoad.config;


@ConfigurationProperties(prefix = "pack.app")
public class PackApp {
    private String title;
    private String version;
    private Integer sno;


    private Security security;


    public PackApp(String title, String version, Integer sno, @DefaultValue("Security [username=null]") Security security) {
        this.title = title;
        this.version = version;
        this.sno = sno;
        this.security = security;
    }


    // getters, setters
}

如果 security 属性没有在配置文件中进行配置,Spring Boot 会将其设置为一个默认值,即 Security [username=null]。

嵌套集合属性的默认值

同样,对于集合类型的嵌套属性,也可以使用 @DefaultValue 注解设置默认值。例如:

package com.icoderoad.config;


@ConfigurationProperties(prefix = "pack.app")
public class PackApp {
    private List<String> roles;


    public PackApp(String title, String version, Integer sno, @DefaultValue({"ADMIN", "MGR"}) List<String> roles) {
        this.roles = roles;
    }
}

如果 roles 属性没有在配置文件中提供,roles 将会使用默认的 {"ADMIN", "MGR"} 值。

Record 类型与默认值

Spring Boot 还支持使用 Record 类型作为配置类,并为 Record 类型的字段设置默认值。例如:

package com.icoderoad.config;


@ConfigurationProperties(prefix = "pack.app")
public record AppRecord(String title, String version, @DefaultValue("999") Integer sno) {}

这种方式允许我们将默认值应用到 Record 类型的字段,增强了代码的简洁性和类型安全性。

总结

@DefaultValue 注解是 Spring Boot 3.4 中非常实用的功能,它使得我们在属性绑定时能够为缺失的属性提供默认值,减少了因缺失配置而产生的异常和错误。结合构造函数绑定和嵌套属性的默认值功能,@DefaultValue 注解为我们提供了更加灵活和安全的配置方式,极大地提升了代码的可维护性与稳定性。

责任编辑:武晓燕 来源: 路条编程
相关推荐

2010-06-11 14:46:38

可路由协议

2020-11-30 13:12:04

Linux文本命令

2015-01-15 09:34:28

2020-11-11 21:27:55

缓冲文件调用

2018-06-12 11:05:33

2014-06-09 13:21:27

2010-04-16 17:09:18

Oracle查看锁

2019-12-02 14:14:20

缓冲系统调用函数

2025-01-03 17:10:54

2010-10-27 10:39:44

求职

2014-06-20 14:35:48

浪潮数据

2020-01-17 06:12:10

物联网IOT技术

2019-08-18 23:10:14

数据科学算法数学

2021-01-27 09:45:17

负载均衡

2024-03-21 08:57:39

语言软件开发

2015-07-30 17:30:43

Linux命令

2009-06-10 09:08:13

WCF变更处理契约

2015-05-21 10:03:04

应用标题ASO

2009-06-02 16:32:10

IT培训职场白领

2019-08-26 09:50:15

TCP连接Socket
点赞
收藏

51CTO技术栈公众号