springboot如何配置嵌套map和list参数
作者:Jeremy_Lee123
.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();
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。