• SpringBoot读取配置文件的几种方式


    Spring读取配置文件的几种方法,SpringBoot也都支持。具体查看:https://www.cnblogs.com/myitnews/p/14028588.html

    本文主要介绍SpringBoot独有的一种读取方法,使用注解:@ConfigurationProperties。

    使用 @Value 注解或者使用 Spring Environment bean 访问这些属性,是这种注入配置方式有时显得很笨重。使用@ConfigurationProperties )来获取这些属性会更灵活。

    @ConfigurationProperties 的基本用法非常简单:为每个要捕获的外部属性提供一个带有字段的类。请注意以下几点:

    • 前缀定义了哪些外部属性将绑定到类的字段上
    • 根据 Spring Boot 宽松的绑定规则,类的属性名称必须与外部属性的名称匹配
    • 我们可以简单地用一个值初始化一个字段来定义一个默认值
    • 类本身可以是包私有的
    • 类的字段必须有公共 setter 方法

    Spring 宽松绑定规则 (relaxed binding)

    Spring使用一些宽松的绑定属性规则。因此,以下变体都将绑定到 hostName 属性上:

    mail.hostName=localhost
    mail.hostname=localhost
    mail.host_name=localhost
    mail.host-name=localhost
    mail.HOST_NAME=localhost

    一、激活@ConfigurationProperties

    • 添加@Component等注组件注解
    • 通过 Spring 的 Java Configuration 特性实现(@Bena)。
    • 使用@EnableConfigurationProperties 注解
      • 该注解中其实是用了@Import(EnableConfigurationPropertiesImportSelector.class) 实现(不推荐)。

    二、无法转换的属性和未知的属性

    无法转换的属性

    如果我们在 application.properties 属性上定义的属性不能被正确的解析会发生什么?默认情况下,Spring Boot 将会启动失败,并抛出异常。

    当我们为属性配置错误的值时,而又不希望 Spring Boot 应用启动失败,我们可以设置 ignoreInvalidFields 属性为 true (默认为 false)。

    未知的属性

    如果我们在 application.properties 文件提供了 MailModuleProperties 类不知道的属性会发生什么?

    默认情况下,Spring Boot 会忽略那些不能绑定到 @ConfigurationProperties 类字段的属性。
    然而,当配置文件中有一个属性实际上没有绑定到 @ConfigurationProperties 类时,我们可能希望启动失败。也许我们以前使用过这个配置属性,但是它已经被删除了,这种情况我们希望被触发告知手动从 application.properties 删除这个属性。
    为了实现上述情况,我们仅需要将 ignoreUnknownFields 属性设置为 false (默认是 true)。

    弃用警告⚠️(Deprecation Warning)
    ignoreUnknownFields 在未来 Spring Boot 的版本中会被标记为 deprecated,因为我们可能有两个带有 @ConfigurationProperties 的类,同时绑定到了同一个命名空间 (namespace) 上,其中一个类可能知道某个属性,另一个类却不知道某个属性,这样就会导致启动失败

    三、启动时校验 @ConfigurationProperties

     如果我们希望配置参数在传入到应用中时有效的,我们可以通过在字段上添加 bean validation 注解,同时在类上添加 @Validated 注解。

    应用启动时,我们将会得到 BindValidationException。

    当然这些默认的验证注解不能满足你的验证要求,我们也可以自定义注解。

    如果你的验证逻辑很特殊,我们可以实现一个方法,并用 @PostConstruct 标记,如果验证失败,方法抛出异常即可。

    四、复杂属性类型

    多数情况,我们传递给应用的参数是基本的字符串或数字。但是,有时我们需要传递诸如 List 的数据类型。

    List 和 Set

    我们有两种方式让 Spring Boot 自动填充该 list 属性。

    (1) application.properties

    在 application.properties 文件中以数组形式书写:

    (2) application.yml

    YAML 本身支持 list 类型,所以可以在 application.yml 文件中添加:

    set 集合也是这种方式的配置方式,不再重复书写。另外YAML 是更好的阅读方式,层次分明,所以在实际应用中更推荐大家使用该种方式做数据配置。

    Map<String, String>

    SpringBoot也支持Map<String,String>的读取。

    1、application.properties配置如下:

    fyk.db-script.check-sql.[1-FYK_PROPERTIES-DQL]=select case when exists(select 1 from all_tables t where t.TABLE_NAME = upper('fyk_properties')) then 1 else 0 end as result from dual
    fyk.db-script.check-sql.[2-FYK_PROPERTIES-DML-fyk-oauth]=select case when exists(select 1 from fyk_properties t where t.application='fyk-oauth') then 1 else 0 end as result from dual

    注意:如果Map类型的key包含非字母数字和-的字符,需要用[]括起来,否则不需要使用中括号。

    2、配置类读取如下:

    @Component
    @ConfigurationProperties(prefix = "fyk.db-script")
    public class CheckSqlProperties {
        private Map<String, String> checkSql;
    
        public Map<String, String> getCheckSql() {
            return checkSql;
        }
    
        public void setCheckSql(Map<String, String> checkSql) {
            this.checkSql = checkSql;
        }
    }

    3、扩展:使用@Value的方式获取

    要使用@Value的方式获取,首先配置文件中,配置的方式要改下,如下:

    fyk.db-script.check-sql={
      "1-FYK_PROPERTIES-DQL":"select case when exists(select 1 from all_tables t where t.TABLE_NAME = upper('fyk_properties')) then 1 else 0 end as result from dual",
      "2-FYK_PROPERTIES-DML-fyk-oauth":"select case when exists(select 1 from fyk_properties t where t.application='fyk-oauth') then 1 else 0 end as result from dual"
      }

    注意:如果Map类型的key包含非字母数字和-的字符,需要用引号括起来,否则不需要使用引号(建议都用上引号);value值,都必须要用引号括起来。

    在使用该配置的地方,使用@Value的使用获取:

    @Value("#{${fyk.db-script.check-sql}}")
    private Map<String, String> checkSql
    Duration

    Spring Boot 内置支持从配置参数中解析 durations (持续时间)。

    我们既可以配置毫秒数数值,也可配置带有单位的文本。

    配置 duration 不写单位,默认按照毫秒来指定,我们也可已通过 @DurationUnit 来指定单位。

    常用单位如下:

    • ns for nanoseconds (纳秒)
    • us for microseconds (微秒)
    • ms for milliseconds (毫秒)
    • s for seconds (秒)
    • m for minutes (分)
    • h for hours (时)
    • d for days (天)
    DataSize

    与 Duration 的用法一样,默认单位是 byte (字节),可以通过 @DataSizeUnit 单位指定。

    添加配置

    但是,我测试的时候打印出来结果都是以 B (bytes) 来显示

    常见单位如下:

    • B for bytes
    • KB for kilobytes
    • MB for megabytes
    • GB for gigabytes
    • TB for terabytes
    自定义类型

    有些情况,我们想解析配置参数到我们自定义的对象类型上,假设,我们我们设置最大包裹重量:

    在 MailModuleProperties 中添加 Weight 属性

    我们可以模仿 DataSize 和 Duration 创造自己的 converter (转换器)

    将其注册到 Spring Boot 上下文中

    @ConfigurationPropertiesBinding 注解是让 Spring Boot 知道使用该转换器做数据绑定。

    五、使用 Spring Boot Configuration Processor 完成自动补全

    添加依赖:

    重新 build 项目之后,configuration processor 会为我们创建一个 JSON 文件:

    这样,当我们在 application.properties 和 application.yml 中写配置的时候会有自动提醒。

    六、标记配置属性为 Deprecated

    configuration processor 允许我们标记某一个属性为 deprecated

    我们可以通过添加 @DeprecatedConfigurationProperty 注解到字段的 getter 方法上,来标示该字段为 deprecated,重新 build 项目,看看 JSON 文件发生了什么?

    当我们再编写配置文件时,已经给出了明确 deprecated 提示:

    七、总结

    Spring Boot 的 @ConfigurationProperties 注解在绑定类型安全的 Java Bean 时是非常强大的,我们可以配合其注解属性和 @DeprecatedConfigurationProperty 注解获取到更友好的编程方式,同时这样让我们的配置更加模块化。

    注意:如果使用 SpEL 表达式,我们只能选择 @Value 注解。

    转自:https://www.cnblogs.com/jimoer/p/11374229.html

  • 相关阅读:
    1024. Palindromic Number (25)
    Android 它们的定义View
    Acdreamoj1116(Gao the string!)弦hash+二分法+矩阵高速功率
    Linux SVNserver建立
    JavaScript window.location物
    [D3] Reuse Transitions in D3 v4
    [D3] Animate Transitions in D3 v4
    [D3] Debug D3 v4 with Dev Tools
    [Angular] Custom directive Form validator
    [D3] Build an Area Chart with D3 v4
  • 原文地址:https://www.cnblogs.com/myitnews/p/14067465.html
Copyright © 2020-2023  润新知