springboot如何配置嵌套map和list参数

 更新时间:2025年03月25日 09:18:48   作者:Jeremy_Lee123  
这篇文章主要介绍了springboot如何配置嵌套map和list参数问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

.properties文件中存放一组配置参数,分别为map类型和list类型,包含各种嵌套的map<String,List<String>>,List<Map<String,String>>,map<String,List<Pojo>>,List<Map<String,Pojo>>等复杂类型,做测试方式,读取配置参数。

一、初级版--Map<String,String>和List<String>

1.1、配置文件application.properties添加如下参数

#map 第一种方式
data.mapConfig.key01=java
data.mapConfig.key02=hadoop
data.mapConfig.key03=flink
#map 第二种方式(推荐)
data.mapConfig[key01]=java
data.mapConfig[key02]=hadoop
data.mapConfig[key03]=flink
#list 第一种方式
data.listConfig[0]=apple0
data.listConfig[1]=apple1
data.listConfig[2]=apple2
#list 第二种方式(推荐)
data.listConfig=apple0,apple1,apple2

1.2、编写MapListConfig类,用来读取配置信息

package com.lxk.alarm.unified;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

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

@Configuration
@ConfigurationProperties(prefix = "data")
//如果只有一个主配置类文件,@PropertySource可以不写
@PropertySource("classpath:application.properties")
public class MapListConfig {
    /**
     * data.mapConfig
     * 这里map名需要和application.properties中的参数一致
     */
    private Map<String, String> mapConfig = new HashMap<>();
    /**
     * data.listConfig
     * 这里list名需要和application.properties中的参数一致
     */
    private List<String> listConfig = new ArrayList<>();

    /**
     * 编写get,set方法方便使用
     */
    public Map<String, String> getMapConfig() {        return mapConfig;    }
    public void setMapConfig(Map<String, String> mapConfig) {        this.mapConfig = mapConfig;    }
    public List<String> getListConfig() {        return listConfig;    }
    public void setListConfig(List<String> listConfig) {        this.listConfig = listConfig;    }
}

1.3、测试类测试

package com.lxk.alarm.unified;


@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootTest {
    @Autowired
    private MapListConfig mapListConfig;

    @Test
    public void mapListTest() {
        Map<String, String> map = mapListConfig.getMapConfig();

        List<String> list = mapListConfig.getListConfig();

        System.out.println("Map<String, String>:  "+JSON.toJSONString(map));
        System.out.println("List<String>:  "+ JSON.toJSONString(list));
    }
}

//输出结果

Map<String, String>: {"key03":"flink","key02":"hadoop","key01":"java"}
List<String>: ["apple0","apple1","apple2"]

补充另一种自动注入:

@Value("#{'${data.listConfig}'.split(',')}")
private List<String> list;

二、中级版--map<String,List<String>>和List<Map<String,String>>

2.1、配置文件application.properties添加如下参数

#map-- map<String,List<String>>
data01.mapList.key01[0]=java
data01.mapList.key01[1]=hadoop
data01.mapList.key01[2]=flink
data01.mapList.key02[0]=pyhthon
data01.mapList.key02[1]=c++
data01.mapList.key02[2]=scala

#list -- List<Map<String,String>>
data01.listMap[0].key01=apple0
data01.listMap[0].key02=apple1
data01.listMap[1].key01=apple3
data01.listMap[1].value02=apple4

2.2、编写MapListConfig02类,用来读取配置信息

package com.lxk.alarm.unified;

@Configuration
@ConfigurationProperties(prefix = "data01")
//如果只有一个主配置类文件,@PropertySource可以不写
@PropertySource("classpath:application.properties")
public class MapListConfig02 {
    /**
     * data.mapConfig
     * 这里map名需要和application.properties中的参数一致
     */
    private Map<String,List<String>> mapList = new HashMap<>();
    /**
     * data.listConfig
     * 这里list名需要和application.properties中的参数一致
     */
    private List<Map<String,String>> listMap = new ArrayList<>();

    /**
     * 编写get,set方法方便使用
     */
    public Map<String, List<String>> getMapList() {        return mapList;    }
    public void setMapList(Map<String, List<String>> mapList) {        this.mapList = mapList;    }
    public List<Map<String, String>> getListMap() {        return listMap;    }
    public void setListMap(List<Map<String, String>> listMap) {        this.listMap = listMap;    }
}

2.3、测试类测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootTest {
    @Autowired
    private MapListConfig mapListConfig;

    @Autowired
    private MapListConfig02 mapListConfig02;


    @Test
    public void mapListTest02() {
        Map<String, List<String>> mapList = mapListConfig02.getMapList();

        List<Map<String, String>> listMap = mapListConfig02.getListMap();

        System.out.println("Map<String, List<String>>:  "+JSON.toJSONString(mapList));
        System.out.println("List<Map<String, String>>:  "+ JSON.toJSONString(listMap));
    }
}

//输出结果
Map<String, List<String>>: {"key02":["pyhthon","c++","scala"],"key01":["java","hadoop","flink"]}
List<Map<String, String>>: [{"key01":"apple0","key02":"apple1"},{"key01":"apple3","value02":"apple4"}]

三、高级版--Map<String,List<Pojo>>和List<Map<String,Pojo>>

3.1、配置文件application.properties添加如下参数

#第三种
#map-- map<String,List<POJO>>
data02.mapList.key01[0].name=zhangsan
data02.mapList.key01[0].sex=male
data02.mapList.key01[0].age=30
data02.mapList.key01[1].name=lisi
data02.mapList.key01[1].sex=female
data02.mapList.key01[1].age=33
data02.mapList.key02[0].name=wangwu
data02.mapList.key02[0].sex=male
data02.mapList.key02[0].age=35

#list -- List<Map<String,POJO>>
data02.listMap[0].key01[name]=zhangsan
data02.listMap[0].key01[sex]=male
data02.listMap[0].key01[age]=17
data02.listMap[1].key01[name]=lisi
data02.listMap[1].key01[sex]=female
data02.listMap[1].key01[age]=18

3.2、编写MapListConfig03类,用来读取配置信息

package com.lxk.alarm.unified;

@Configuration
@ConfigurationProperties(prefix = "data02")
//如果只有一个主配置类文件,@PropertySource可以不写
@PropertySource("classpath:application.properties")
public class MapListConfig03 {
    /**
     * data.mapConfig
     * 这里map名需要和application.properties中的参数一致
     */
    private Map<String,List<Person>> mapList = new HashMap<>();
    /**
     * data.listConfig
     * 这里list名需要和application.properties中的参数一致
     */
    private List<Map<String,Person>> listMap = new ArrayList<>();

    /**
     * 编写get,set方法方便使用
     */
    public Map<String, List<Person>> getMapList() {        return mapList;    }
    public void setMapList(Map<String, List<Person>> mapList) {        this.mapList = mapList;    }
    public List<Map<String, Person>> getListMap() {        return listMap;    }
    public void setListMap(List<Map<String, Person>> listMap) {        this.listMap = listMap;    }
}

3.3、测试类测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootTest {
    @Autowired
    private MapListConfig mapListConfig;

    @Autowired
    private MapListConfig02 mapListConfig02;

    @Autowired
    private MapListConfig03 mapListConfig03;

    @Autowired private Environment env;

    @Test
    public void mapListTest03() {
        Map<String, List<Person>> mapList = mapListConfig03.getMapList();

        List<Map<String, Person>> listMap = mapListConfig03.getListMap();

        System.out.println("Map<String, List<Person>>:  "+JSON.toJSONString(mapList));
        System.out.println("List<Map<String, Person>:  "+ JSON.toJSONString(listMap));
    }
}

//输出结果
Map<String, List<Person>>: {"key02":[{"age":35,"name":"wangwu","sex":"male"}],"key01":[{"age":30,"name":"zhangsan","sex":"male"},{"age":33,"name":"lisi","sex":"female"}]}
List<Map<String, Person>: [{"key01":{"age":17,"name":"zhangsan","sex":"male"}},{"key01":{"age":18,"name":"lisi","sex":"female"}}]

3.4、FAQ: Field required a single bean, but 2 were found

解决:添加@Primary告诉spring初始化时使用哪个主要的实现类。

(1)@Autowired

@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。

@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。如下:

(2)@Resource

@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。

四、四种方式获取配置

4.1、@ConfigurationProperties方式 +(prefix = "data")

适用于Map和List配置,需要加前缀‘prefix

4.2、使用@Value注解方式

适用于单个key=value

4.3、使用自带Environment

适用于单个key=value

import org.springframework.core.env.Environment;
@Autowired private Environment env;

...

map.put("type", env.getProperty("data.listConfig"));
map.put("title", new String(env.getProperty("data.listConfig").getBytes("ISO-8859-1"), "UTF-8")); // 解决中文乱码

4.4、使用自带Environment

  • 方式一:Properties properties = PropertiesLoaderUtils.loadAllProperties("sql.properties");
  • 方式二:由于配置文件一般同时全局的,能够经过PropertiesListener的监听经行启动的时候就获取到。能够避免每调用一次方法就加载一次

1.编写一个配置文件监听的类PropertiesListener

每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发java

public class PropertiesListener implements ApplicationListener<ApplicationStartedEvent> {
    private String propertyFileName;
    public PropertiesListener(String propertyFileName) {
        this.propertyFileName = propertyFileName;
    }
    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        PropertiesListenerConfig.loadAllProperties(propertyFileName);
    }
}

2.在编写一个配置文件的加载类PropertiesListenerConfigweb

public class PropertiesListenerConfig {
    public static Map<String, String> propertiesMap = new HashMap<>();
    
    private static void processProperties(Properties props) throws BeansException {
        propertiesMap = new HashMap<String, String>();
        for (Object key : props.keySet()) {
            String keyStr = key.toString();
            try {
                // PropertiesLoaderUtils的默认编码是ISO-8859-1,在这里转码一下
                propertiesMap.put(keyStr, new String(props.getProperty(keyStr).getBytes("ISO-8859-1"), "utf-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (java.lang.Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void loadAllProperties(String propertyFileName) {
        try {
            Properties properties = PropertiesLoaderUtils.loadAllProperties(propertyFileName);
            processProperties(properties);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getProperty(String name) {
        return propertiesMap.get(name).toString();
    }

    public static Map<String, String> getAllProperty() {
        return propertiesMap;
    }
}

3.在springboot的启动类上面添加监听spring

public static ApplicationContext applicationContext;

      public static void main(String[] args) {
		  SpringApplication application = new SpringApplication(WebApp.class);
	       // 第四种方式:注册监听器
          application.addListeners(new PropertiesListener("sql.properties"));
          applicationContext =  application.run(args);
     }
 }

4.在方法上调用经过PropertiesListenerConfig.getAllProperty();调用sql

Map<String, String> allProperty = PropertiesListenerConfig.getAllProperty();

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 深入解析System.load 与 System.loadLibrary

    深入解析System.load 与 System.loadLibrary

    以下是对System.load与System.loadLibrary进行了详细的分析介绍。需要的朋友可以过来参考下
    2013-08-08
  • Java实现XML与JSON的互相转换详解

    Java实现XML与JSON的互相转换详解

    这篇文章主要为大家详细介绍了如何使用Java实现XML与JSON的互相转换,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-03-03
  • Java web xml文件读取解析方式

    Java web xml文件读取解析方式

    这篇文章主要介绍了Java web xml文件读取解析方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 解决若依微服务框架启动报错的问题

    解决若依微服务框架启动报错的问题

    Invalid bound statement错误通常由MyBatis映射文件未正确加载或Nacos配置未读取导致,需检查XML的namespace与方法ID是否匹配,确认资源目录配置,确保bootstrap.yml中Nacos配置路径正确加载
    2025-08-08
  • Java下变量大小写驼峰、大小写下划线、大小写连线转换

    Java下变量大小写驼峰、大小写下划线、大小写连线转换

    有时候需要处理对象属性的getter、setter方法,或者将属性与数据表字段进行相互转换,感兴趣的可以了解一下
    2021-06-06
  • Spring MVC实现GET请求接收Date类型参数

    Spring MVC实现GET请求接收Date类型参数

    这篇文章主要介绍了Spring MVC实现GET请求接收Date类型参数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • 图解排序算法之希尔排序Java实现

    图解排序算法之希尔排序Java实现

    希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。本文会以图解的方式详细介绍希尔排序的基本思想及其代码实现
    2021-06-06
  • jenkins按模块进行构建遇到的问题及解决方案

    jenkins按模块进行构建遇到的问题及解决方案

    这篇文章主要介绍了jenkins按模块进行构建的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • Java Stream流与使用操作指南

    Java Stream流与使用操作指南

    Stream不是数据结构,而是一种高级的数据处理工具,允许你以声明式的方式处理数据集合,类似于SQL语句操作数据库,本文给大家介绍Java Stream流与使用操作指南,感兴趣的朋友一起看看吧
    2025-08-08
  • MyBatis-Plus未集成SQL语句的场景与解决方案

    MyBatis-Plus未集成SQL语句的场景与解决方案

    MyBatis-Plus 提供了强大的 CRUD 操作和条件构造器,但在某些复杂场景下仍需手动编写 SQL 语句,以下是常见未集成场景及对应的实现方式,需要的朋友可以参考下
    2025-09-09

最新评论