美文网首页
SpringBoot读取Properties和Yaml文件

SpringBoot读取Properties和Yaml文件

作者: EugeneHeen | 来源:发表于2021-11-26 15:22 被阅读0次

    1 序

    SpringBoot.jpg
    • 示例代码(maven分支,load-properties模块):https://gitee.com/eugene-example/springboot
    • 首先,我们通常读取的配置文件是指propertiesyaml两类。无论是使用Maven还是Gradle工具来构建,我们读取都是基于类路径,也就是工程resources目录下存放的文件。本文先讲解读取properties类型的配置文件。
    • SpringBoot配置文件,例如工程resources目录下存放的:bootstrap.propertiesapplication.propertiesapplication-dev.propertiesapplication-prod.properties
    • 用户自定义的配置文件,例如工程resources目录下存放的:config.propertiesdb/ds.properties
    • Spring Framework相关注解说明:
      • @PropertySource注解,使用value属性,来指定加载类路径下的properties文件,读取SpringBoot配置文件时无需使用此注解,直接通过@Value注解读取即可。
      • @Value注解,通过表达式${key.key...}直接读取SpringBoot配置文件的属性。或者结合@ConfigurationProperties注解使用。同时也可使用表达式#{object.prop}来读取对象属性。
      • @ConfigurationProperties注解,使用prefix属性指定读取属性的前缀,可配合@Value注解使用,便于简化读取属性表达式。

    2 示例展示

    2.1 使用的示例文件

    • SpringBoot配置文件:resource\application.properties,内容如下:
    server.port=9999
    
    • 类路径下的用户自定义配置文件:resource\config.properties,内容如下:
    user.name=EugeneHeen
    user.password=12345678
    
    • 类路径下自定义目录存放的用户自定义配置文件:resource\db\ds.yml,内容如下:
    ds:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/eugene
      username: root
      password: 88888888
      pool:
        name: ds-poll
        select: SELECT 1 FROM A
    

    2.2 读取SpringBoot规范的默认配置文件

    1. 通过定义一个POJO封装SpringBoot配置文件的属性读取
    @Data // 通过Lombok提供GET和SET方法
    @ConfigurationProperties(prefix = "server")
    @Component
    public class BootProps {
        private Integer port;
    }
    
    @RestController
    @RequestMapping("/boots")
    public class BootController {
    
        @Autowired
        private BootProps bootProps;
    
        @Value("${server.port}")
        private String port;
    
        @GetMapping("/auth")
        public String auth() {
            return new StringBuilder("SpringBoot Server Port")
                    .append(": ")
                    .append(this.port)
                    .append(", 通过封装Bean获取Port:")
                    .append(this.bootProps.getPort()).toString();
        }
    }
    
    1. 直接在使用的类中通过@Value注解标记示例变量读取,例如,ControllerService
    @RestController
    @RequestMapping("/configs")
    public class BootController {
        @Value("${server.port}")
        private Integer port;
        
        @GetMapping("/value")
        public String value() {
            return new StringBuilder("SpringBoot Server Port")
                    .append(": ")
                    .append(this.port).toString();
         }
     }
    

    2.3 读取用户自定义的配置文件

    1. 通过定义一个POJO类 ,@PropertySource + @Value注解来读取
    @Data
    @PropertySource(value = {"config.properties"})
    @Component
    public class ConfigProps {
        @Value("${user.name}")
        private String name;
        @Value("${user.password}")
        private String password;
    }
    
    • 通过定义一个POJO类 ,@PropertySource + @ConfigurationProperties注解来简化读取,也可配合@Value注解使用。这种方法对YAML文件无效,后续会通过详细示例阐述如何解决此问题
    @Data
    @PropertySource(value = {"db/ds.properties"})
    @ConfigurationProperties(prefix = "master")
    @Component
    public class DsProps {
        private String username;
    
        private String password;
    }
    

    经实际测试,SpringBoot2.3+的版本,会自动将配置文件中的单词-连接的属性,同自定义POJO类中遵循驼峰命名的属性匹配,无需使用@Value注解来完成值读取。例如,1. 配置文件username自动对应POJO类中的userName属性。2. 配置文件driver-class-name自动对应POJO类中的driverClassName属性。

    3 读取用户自定义YAML文件

    3.1 User Define YAML,SpringBoot Say No!我不支持下面这些骚操作

    1. @PropertySource + @Value注解
    2. @PropertySource + @ConfigurationProperties注解

    Tip:@PropertySource不支持YAML文件加载,它仅仅支持Properties文件加载

    3.2 单层级YAML配置文件读取

    1. 单层级 VS 多层级
      • 但层级配置文件
        ds:
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://127.0.0.1:3306/eugene
            username: root
            password: 88888888
        
      • 多层级配置文件
        ds:
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://127.0.0.1:3306/eugene
            username: root
            password: 88888888
            pool:
                name: ds-poll
                select: SELECT 1 FROM A
        
    2. 通过定义一个POJO类 ,@PropertySource + @ConfigurationProperties + @Value注解来实现单层级YAML配置文件读取
    @Data
    @PropertySource(value = {"db/ds.yml"})
    @ConfigurationProperties(prefix = "ds")
    @Component
    public class DsYaml {
        @Value("${driver-class-name}")
        private String driverClassName;
    
        @Value("${username}")
        private String userName;
    
        @Value("${password}")
        private String password;
    }
    

    3.3 多层级YAML配置文件读取

    1. User Define YAML,SpringBoot Only Supports!我仅支持唯一的骚操作

      • @PropertySource指定factory属性为自定义DefaultPropertySourceFactory的扩展类 + @Value注解(别再瞎搞!切记!此处无法再使用@ConfigurationProperties注解的prefix属性指定前缀了)
    2. 关于Spring Framework中与配置文件相关的3个类:

      • YamlPropertiesFactoryBean:用于将YAML文件加载为Properties文件。
      • YamlMapFactoryBean:用于将YAML文件加载为Map对象。
      • DefaultPropertySourceFactory@PropertySource注解中的factory属性默认使用的实现类。
    3. 扩展DefaultPropertySourceFactory类,自定义YAML文件加载工厂类

    public class YamlPropertySourceFactory extends DefaultPropertySourceFactory {
        public YamlPropertySourceFactory() {
            super();
        }
    
        @Override
        public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
            String sourceName = Optional.ofNullable(name).orElse(resource.getResource().getFilename());
            if (!resource.getResource().exists()) {
                // return an empty Properties
                return new PropertiesPropertySource(sourceName, new Properties());
            } else if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml")) {
                Properties propertiesFromYaml = loadYaml(resource);
                return new PropertiesPropertySource(sourceName, propertiesFromYaml);
            } else {
                return super.createPropertySource(name, resource);
            }
        }
    
        /**
         * 加载YAML文件
         * @param resource YAML文件
         * @return Properties对象
         * @throws IOException 文件加载异常
         */
        private Properties loadYaml(EncodedResource resource) throws IOException {
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            factory.setResources(resource.getResource());
            factory.afterPropertiesSet();
            return factory.getObject();
        }
    }
    
    1. 加载多层级YAML配置文件
    @Data
    @PropertySource(factory = YamlPropertySourceFactory.class, value = {"db/ds.yml"})
    @Component
    public class DsAYaml {
        @Value("${ds.driver-class-name}")
        private String driverClassName;
    
        @Value("${ds.username}")
        private String userName;
    
        @Value("${ds.password}")
        private String password;
    
        @Value("${ds.pool.name}")
        private String poolName;
    
        @Value("${ds.pool.select}")
        private String poolSelect;
    }
    

    相关文章

      网友评论

          本文标题:SpringBoot读取Properties和Yaml文件

          本文链接:https://www.haomeiwen.com/subject/ghfztrtx.html