springboot 加载一个properties文件转换为对象、List和Map数据结构

一、springboot 加载一个properties文件转换为对象

1.1、配置文件-blog.properties

com.chenheng.blog.name=陈大大
com.chenheng.blog.title=Spring Boot学习教程
com.chenheng.blog.desc=${com.chenheng.blog.name}正在努力写《${com.chenheng.blog.title}》
# 随机字符串
com.chenheng.blog.value=${random.value}
# 随机int
com.chenheng.blog.number=${random.int}
# 随机long
com.chenheng.blog.bignumber=${random.long}
# 10以内的随机数
com.chenheng.blog.test1=${random.int(10)}
# 10-20的随机数
com.chenheng.blog.test2=${random.int[10,20]}

1.2、Blog2Properties类

package com.chenheng.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * @author chenheng
 * @date 2022/4/30 21:17
 */
@PropertySource(value={"classpath:config/blog.properties"})
@ConfigurationProperties(prefix = "com.chenheng.blog")
@Component
@Data
public class Blog2Properties {
    private String name;
    private String title;
    private String desc;
    private String value;
    private String number;
    private String bignumber;
    private String test1;
    private String test2;
}

1.3、运行

package com.chenheng;

import com.chenheng.properties.Blog2Properties;
import com.chenheng.properties.BlogProperties;
import com.chenheng.properties.PersonProperties;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
 * @author chenheng
 * @date 2022/4/30 20:49
 */
@SpringBootTest
public class SpringBootTest01 {
    @Autowired
    private Blog2Properties blog2Properties;
    @Test
    void testProperties02(){
        System.out.println(blog2Properties);
    }
}

二、springboot 加载一个properties文件转换为List

2.1、配置文件-cityCode.properties

#List properties
com.city.code.list[0]=www
com.city.code.list[1]=localhost
com.city.code.list[2]=wuhan
com.city.code.list[3]=tianjin
#Map Properties
com.city.code.map.www=4201
com.city.code.map.wuhan=4201
com.city.code.map.tianjin=1200

2.2、CityCodeProperties类

package com.chenheng.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author chenheng
 * @date 2022/5/1 14:39
 */
@PropertySource(value={"classpath:config/cityCode.properties"})
@ConfigurationProperties(prefix = "com.city.code")
@Component
@Data
public class CityCodeProperties {
    private List<String> list = new ArrayList<>();

    private Map<String, String> map = new HashMap<>();
}

2.3、运行

package com.chenheng;

import com.chenheng.properties.Blog2Properties;
import com.chenheng.properties.BlogProperties;
import com.chenheng.properties.CityCodeProperties;
import com.chenheng.properties.PersonProperties;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Map;

/**
 * @author chenheng
 * @date 2022/4/30 20:49
 */
@SpringBootTest
public class SpringBootTest01 {
    @Autowired
    private CityCodeProperties cityCodeProperties;
    @Test
    void testCityCodeProperties(){
        List<String> list = cityCodeProperties.getList();
        Map<String, String> map = cityCodeProperties.getMap();
        System.out.println(list + "->" + map);
    }
}

三、springboot 加载一个properties文件转换为Map

前言

springboot中比较常见的获取properties中的值,就是直接在字段上面添加@Value的属性.
但有时候我们不确定key有多少, 但会有一定的规律(这个规律是根据业务来定的,如下), 这时候我们就可以考虑将properties中的信息转换为一个map, 然后根据key的规律操作响应的数据

1. 创建一个properties文件, properties文件内容:

名称为
customExportFields.properties
文件路径为
在这里插入图片描述
内容为

#15-排名
custom.customData.15=rank
#17-店铺ID
custom.customData.17=shopId

2、在java中将该properties文件转换为map

package com.xxx.config;

import java.util.HashMap;
import java.util.Map;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

// lombok专用注解
@Data
// 指定配置文件
@PropertySource("classpath:config/customExportFields.properties")
// custom指的是customExportFields.properties中前缀
@ConfigurationProperties(prefix = "custom")
@Component
public class CustomExportPropertiesConfig {
// prefix的值+customData变量名为properties key的前一部分, 将key剩余的部分作为map的key, value作为map的value
  public Map<String, String> customData = new HashMap<>();
}

3、注意事项

customExportFields.properties文件中

custom.customData.15=rank

对象JavaConfig类中

属性文件中的custom是@ConfigurationProperties(prefix = "custom")对应的前缀名称
属性文件中的customData即是Map<String, String> customData = new HashMap<>()中customData集合的变量名,这一点一定要注意,不然找不到值
属性文件中的15即是customData集合中的key,而rank是customData集合中15这个key所对应的value值

四、遇到的问题:@PropertySource 注解实现读取 yml 文件

4.1、配置文件-person.yml

person:
  name: lucy
  age: 16
  addr: 北京
  books: [java,kafka,netty]
  course-map-teacher: {key1: v1,key2: v2}
  dog:
    name: ${person.name}
    age: ${random.int(5)} #表达式

4.2、PersonProperties类

package com.chenheng.properties;

import factory.MyPropertySourceFactory;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * @author chenheng
 * @date 2022/4/30 22:19
 * @PropertySource 默认的无法读取yml文件,需要写一个类即MyPropertySourceFactory
 * https://juejin.cn/post/6844903768308334606
 */
@PropertySource(value={"classpath:config/person.yml"},encoding = "utf-8",factory = MyPropertySourceFactory.class)
@ConfigurationProperties(prefix = "person")
@Component
@Data
public class PersonProperties {
    private String name;

    private int age;

    private String addr;

    private List<String> books;

    private Map<String, String> courseMapTeacher;

    private Dog dog;
}

4.3、MyPropertySourceFactory 类

在实际的开发中使用 @PropertySource 注解无法加载 yml 配置文件问题,需要继承DefaultPropertySourceFactory类,重写createPropertySource方法

package factory;

import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;

import java.io.IOException;
import java.util.List;

/**
 * @author chenheng
 * @date 2022/4/30 22:34
 */
public class MyPropertySourceFactory extends DefaultPropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        if (resource == null){
            return super.createPropertySource(name, resource);
        }
        List<PropertySource<?>> sources = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource());
        return sources.get(0);
    }
}

4.4、运行

package com.chenheng;

import com.chenheng.properties.Blog2Properties;
import com.chenheng.properties.BlogProperties;
import com.chenheng.properties.CityCodeProperties;
import com.chenheng.properties.PersonProperties;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Map;

/**
 * @author chenheng
 * @date 2022/4/30 20:49
 */
@SpringBootTest
public class SpringBootTest01 {
    @Autowired
    private PersonProperties personProperties;
    @Test
    void testPersonProperties(){
        System.out.println(personProperties);
    }
}

五、参考链接

1、springboot 加载一个properties文件转换为map
2、Springboot读取properties配置文件的List、Map格式的配置项(属性)
3、SpringBoot 从配置文件读取值到对象中
4、@PropertySource 注解实现读取 yml 文件
5、@PropertySource 解析 yml 配置文件,自定义解析 yaml 工厂类
6、@PropertySource 注解的使用

### Spring Boot 中 YAML 文件的使用与配置 #### 1. 基本语法介绍 YAML 是一种简洁的人类可读的数据序列化标准,广泛用于配置文件。在 Spring Boot 应用程序中,`application.yml` 或 `application.properties` 可以用来存储应用程序的各种配置参数。 对于复杂数据结构如列表、数组映射表 (Map),可以采用特定的方式进行定义: - **键值对形式**:这是最简单的表示方法,适用于基本类型的属性设置。 ```yaml server: port: 8080 ``` - **嵌套对象**:通过缩进来表达层次关系,每级缩进两个空格。 ```yaml my-app: name: MyAppName version: "1.0" ``` - **List/Array 类型**:利用连字符 `-` 来指定列表项;也可以放在同一行并用逗号分隔多个元素。 ```yaml environments: active-profiles: ["dev", "test"] servers: - host: localhost port: 9000 - host: remotehost port: 9001 ``` - **Map 类型**:可以通过冒号后面跟上一对或多对键值来创建 map 结构[^1]。 ```yaml my-node: node: key1: value1 key2: value2 ``` #### 2. 数据绑定到 Java Bean 属性 为了使上述配置生效并将这些配置自动注入到Java bean中,在实体类里声明相应的字段,并配合使用注解完成依赖注入操作。例如要获取名为 `my-node.node` 下面所有的子节点作为 Map 形式的实例变量,则可以在对应的 POJO 类内这样写: ```java @Data public class Test { @Value("#{${my-node.node}}") private Map<String, String> instanceMap; } ``` 这里需要注意的是当涉及到复杂的类型转换时可能会遇到一些问题,比如直接尝试将整个 section 映射成一个 Map 对象可能不会按预期工作,这时就需要更加细致地调整配置方式或者借助其他工具辅助实现[^2]。 #### 3. 错误处理建议 如果发现无法成功加载或解析某些配置项,应该仔细检查以下几个方面: - 确认 yaml 文件中的格式正确无误; - 查看日志输出寻找潜在异常信息; - 尝试简化配置测试是否为某个具体条目引起的问题; - 考虑升级 spring-boot 版本来获得更好的兼容性支持特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值