Properties配置加载(@PropertySource),额外不定的配置项单独存储到Map的一次歧路记录和正确解决思路

本文主要是介绍Properties配置加载(@PropertySource),额外不定的配置项单独存储到Map的一次歧路记录和正确解决思路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 背景

笔者的一个微服务的配置是ini文件中存储的。通过下面的方式加载。

@Data
@EqualsAndHashCode(callSuper = true)
@Component
@PropertySource(value={"file:${app.config.common.path}" , "file:${app.config.path}"} , ignoreResourceNotFound=false, encoding="utf-8" , name="app-config" , factory = PropertiesExSourceFactory.class)
public class AppConfig extends AppConfCommon
{	@Value("${authcenter.appkey}")String authCenterAppKey ;@Value("${authcenter.appsecret}")String authCenterAppSecret ;@Value("${sailPyAi.url}")String sailPyAiUrl ;}

现在有一些必定数量的参数,它们都以固定的前缀开始,例如

ai.models.glm-4=xxxx
ai.models.bigwatt=xxx

想把ai.models.*的配置都收集到一起

2. 错误的尝试

此尝试,虽然失败,但里面有一些信息觉得有必要记录一下。
过程:

  1. 定义一个Map
public class AppConfig extends AppConfCommon
{	@Value("${authcenter.appkey}")String authCenterAppKey ;@Value("${authcenter.appsecret}")String authCenterAppSecret ;@Value("${sailPyAi.url}")String sailPyAiUrl ;@Value("${ai.models.*:}")Map<String, Object> aiModels ;
}
  1. 修改PropertiesExSourceFactory,在渠道.*结尾的数据时构造成一个Map返回。
	static class  PropertiesExSource  extends EnumerablePropertySource<PropertiesEx>{public PropertiesExSource(String name, PropertiesEx source) {super(name , source) ;}@Overridepublic Object getProperty(String aName){String propValue = getSource().getProperty(aName) ;if(propValue == null && aName.endsWith(".*")){// 检查键String name = aName.substring(0, aName.length()-1) ;Map<String , Object> map = CS.hashMap() ;PropertiesEx source= getSource() ;for(String propName : source.stringPropertyNames()){if(propName.startsWith(name))map.put(propName , source.getProperty(propName)) ;}if(!map.isEmpty())// 因为Spring框架对@PropertySource源,认为取得的值类型一定是String,返回map会报Map转String错误。// 所以此处把Map转成String格式return new JSONObject(map).toJSONString() ;}return propValue ;}@Overridepublic String[] getPropertyNames(){return getSource().stringPropertyNames().toArray(XArray.sEmptyStringArray) ;}}
  1. 因为目标类型是Map,所以需要一个将JSON字符串转成Map的Converter
public class JsonStrToMapConverter implements Converter<String, Map<String, Object>>
{public JsonStrToMapConverter(){}@Overridepublic Map<String, Object> convert(String source){return XString.isEmpty(source)?CS.hashMap():new JSONObject(source).toMap() ;}
}

4.注册这个Converter
因为配置文件加载较早,所以用下面的方式添加Converter

public class DefaultAppRunLsn implements ApplicationListener<ApplicationEvent>
{	// 省略@Overridepublic void onApplicationEvent(ApplicationEvent event){if(event instanceof ApplicationPreparedEvent){ConfigurableApplicationContext ctx = ((ApplicationPreparedEvent)event).getApplicationContext() ;ConversionService cs = ctx.getBeanFactory().getConversionService() ;if(cs instanceof ConverterRegistry){ConverterRegistry reg = (ConverterRegistry)cs ;reg.addConverter(new JsonStrToMapConverter());}// 省略}else if(event instanceof ServletWebServerInitializedEvent){// 省略}}
}

这么做,如果只有一个PropertySource,没有问题,但是有多个的时候,会有问题,原因就是用@Value方式注入,多个PropetySource在一个池子里了,第2步中的getSource()不一定是当前@value字段所在的那个PropertySource了。

3. 正确做法

单独在定义一个配置类。如下:

@Component
@PropertySource(value="file:${app.config.path}" , ignoreResourceNotFound=false, encoding="utf-8" , name="ai-models" , factory = PropertiesExSourceFactory.class)
@ConfigurationProperties(prefix = "ai")
public class AiModelsConf
{Properties models ;public Properties getModels(){return mConf;}public void seModels(Properties aConf){mConf = aConf;}
}

这篇关于Properties配置加载(@PropertySource),额外不定的配置项单独存储到Map的一次歧路记录和正确解决思路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/974438

相关文章

Spring配置扩展之JavaConfig的使用小结

《Spring配置扩展之JavaConfig的使用小结》JavaConfig是Spring框架中基于纯Java代码的配置方式,用于替代传统的XML配置,通过注解(如@Bean)定义Spring容器的组... 目录JavaConfig 的概念什么是JavaConfig?为什么使用 JavaConfig?Jav

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

Python中4大日志记录库比较的终极PK

《Python中4大日志记录库比较的终极PK》日志记录框架是一种工具,可帮助您标准化应用程序中的日志记录过程,:本文主要介绍Python中4大日志记录库比较的相关资料,文中通过代码介绍的非常详细,... 目录一、logging库1、优点2、缺点二、LogAid库三、Loguru库四、Structlogphp

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

springboot的controller中如何获取applicatim.yml的配置值

《springboot的controller中如何获取applicatim.yml的配置值》本文介绍了在SpringBoot的Controller中获取application.yml配置值的四种方式,... 目录1. 使用@Value注解(最常用)application.yml 配置Controller 中

springboot中配置logback-spring.xml的方法

《springboot中配置logback-spring.xml的方法》文章介绍了如何在SpringBoot项目中配置logback-spring.xml文件来进行日志管理,包括如何定义日志输出方式、... 目录一、在src/main/resources目录下,也就是在classpath路径下创建logba

解决idea启动项目报错java: OutOfMemoryError: insufficient memory

《解决idea启动项目报错java:OutOfMemoryError:insufficientmemory》:本文主要介绍解决idea启动项目报错java:OutOfMemoryError... 目录原因:解决:总结 原因:在Java中遇到OutOfMemoryError: insufficient me

maven异常Invalid bound statement(not found)的问题解决

《maven异常Invalidboundstatement(notfound)的问题解决》本文详细介绍了Maven项目中常见的Invalidboundstatement异常及其解决方案,文中通过... 目录Maven异常:Invalid bound statement (not found) 详解问题描述可

C++多线程开发环境配置方法

《C++多线程开发环境配置方法》文章详细介绍了如何在Windows上安装MinGW-w64和VSCode,并配置环境变量和编译任务,使用VSCode创建一个C++多线程测试项目,并通过配置tasks.... 目录下载安装 MinGW-w64下载安装VS code创建测试项目配置编译任务创建 tasks.js

Nginx概念、架构、配置与虚拟主机实战操作指南

《Nginx概念、架构、配置与虚拟主机实战操作指南》Nginx是一个高性能的HTTP服务器、反向代理服务器、负载均衡器和IMAP/POP3/SMTP代理服务器,它支持高并发连接,资源占用低,功能全面且... 目录Nginx 深度解析:概念、架构、配置与虚拟主机实战一、Nginx 的概念二、Nginx 的特点