在Spring-boot中,为@Value注解添加从数据库读取properties支持

一般我们会把常用的属性放在工程的classpath文件夹中,以property,yaml或json的格式进行文件存储,便于Spring-boot在初始化时获取。 

@Value则是Spring一个非常有用的注解,可以在初始化时很方便的对Bean的入参变量进行赋值,例如:

@Beanpublic BusinessClient businessClient (@Value("http://baseUrl/") String baseUrl) {Retrofit retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .build(); return retrofit.create(BusinessClient .class);

于是,初始化好的Business Client进行http请求时,默认的baseurl都是”http://baseUrl“。
实际上,@Value还支持一种特殊的写法:”${some.proptery.key}”,即将property的key值写在花括号中。例如,我有一个property为aerexu.basurl=http://baseUrl2,将上例中的@Value改写成@Value("${aerexu.basurl}"),baseUrl实际获取到的值是http://baseUrl2。 
这个特性是利用Spring的bean PropertySourcesPlaceholder实现的,Spring boot已经在初始化时帮我们自动实例化了该bean。若是传统的Spring工程,则需要主动实例化,如下:

    @Beanpublic static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); configurer.setPlaceholderPrefix(PlaceholderConfigurerSupport.DEFAULT_PLACEHOLDER_PREFIX); configurer.setPlaceholderSuffix(PlaceholderConfigurerSupport.DEFAULT_PLACEHOLDER_SUFFIX); configurer.setValueSeparator(PlaceholderConfigurerSupport.DEFAULT_VALUE_SEPARATOR); return configurer; }

 

一般情况下,property存在工程中的文件就可以了,但带来的坏处是如果属性需要改变,必须重新发布工程。比如,对接上例中的url,可能会变为https,可能端口会变化。所以,这种类型的属性放在数据库中更合适。
然而将属性存储在数据库中后,@Value对应的值就无法正常解析了。因此,这里提供一种hack的方法,使得@Value可以正常解析。
PropertySourcesPlaceholder在解析属性时,都是从ConfigurableEnvironment中进行寻找的。当ConfigurableEnvironment没有存在的属性时,${}写法的@Value就无法解析了。因此,需要通过特殊的处理,将存储在数据库中的属性注入到ConfigurableEnvironment中。本文定义了一个LoadFromDatabasePropertyConfig类实现该功能,其代码如下:

    @Configuration@Slf4jpublic class LoadFromDatabasePropertyConfig { @Autowired private ConfigurableEnvironment env; @Autowired private SysPropertyResourceMapper propertyResourceMapper; @PostConstruct public void initializeDatabasePropertySourceUsage() { MutablePropertySources propertySources = env.getPropertySources(); try { Map<String, Object> propertyMap = propertyResourceMapper.selectAll().stream() .collect(Collectors.toMap(SysPropertyResource::getPropertyName, SysPropertyResource::getPropertyValue)); Properties properties = new Properties(); properties.putAll(propertyMap); PropertiesPropertySource dbPropertySource = new PropertiesPropertySource("dbPropertySource", properties); Pattern p = Pattern.compile("^applicationConfig.*"); String name = null; boolean flag = false; for (PropertySource<?> source : propertySources) { if (p.matcher(source.getName()).matches()) { name = source.getName(); flag = true; log.info("Find propertySources ".concat(name)); break; } } log.info("========================================================================="); if(flag) { propertySources.addBefore(name, dbPropertySource); } else { propertySources.addFirst(dbPropertySource); } } catch (Exception e) { log.error("Error during database properties setup", e); throw new RuntimeException(e); } } }

上述代码的具体思路是将数据库中的所有需要的属性读出,通过Properties类转换为Spring可用的PropertiesPropertySource,并取名为dbPropertySource。随后利用正则匹配,从已有的所有属性中找到名称以applicationConfig开头的属性(该属性即是所有配置在文件中的property所解析成的对象),并将dbPropertySource存储在其之前。这样当文件和数据库中同时存在key相等的属性时,会优先使用数据库中存储的value。
需要注意的是,上述方案提供的属性解析,必须在数据库相关的bean都实例化完成后才可进行。且为了保证bean在实例化时,数据库属性已经被加入到ConfigurableEnvironment中去了,必须添加@DependsOn注解。上面的BusinessClient的实例化就需更新成:

    @Bean@DependsOn("loadFromDatabasePropertyConfig")public BusinessClient businessClient (@Value("${aerexu.basurl}") String baseUrl) {     Retrofit retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .build(); return retrofit.create(BusinessClient .class);

转载于:https://www.cnblogs.com/bevis-byf/p/11491475.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/482410.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Transformer 会接管人工智能?

来源&#xff1a;ScienceAI编辑&#xff1a;绿萝想象一下&#xff0c;你去当地的五金店&#xff0c;在货架上看到一种新的锤子。你听说过这把锤子&#xff1a;它比其他锤子敲得更快、更准确&#xff0c;在过去的几年里&#xff0c;它已经淘汰了许多其他锤子&#xff0c;至少在大…

SpringBoot防止重复请求,重复表单提交超级简单的注解实现

1. 注解接口 /** * description 防止表单重复提交注解 */Retention(RetentionPolicy.RUNTIME)Target(ElementType.METHOD)Documentedpublic interface DuplicateSubmitToken { //保存重复提交标记 默认为需要保存 boolean save() default true;}2. 定义异常类 /** * 重复提交…

Nat. Commun.速递:合群者有着相似的大脑活动

来源&#xff1a;集智俱乐部作者&#xff1a;郭瑞东 作者&#xff1a;梁金编辑&#xff1a;邓一雪摘要Convergent processing of the world may be a factor that contributes to social connectedness. We use neuroimaging and network analysis to investigate the associat…

桌面推演技术前沿及发展趋势

来源&#xff1a;蓝海长青智库作者&#xff1a;吕欣、蔡梦思、陈彬&#xff0c;国防科技大学系统工程学院摘要桌面推演通过模拟事件场景及处置过程来提高参演人员的风险感知能力、信息研判能力、指挥决策能力和协同配合能力&#xff0c;被广泛应用于军事作战、应急管理和教育培…

清华大学孙茂松:自然语言处理一瞥,知往鉴今瞻未来

来源&#xff1a;中国人工智能学会作者&#xff1a;孙茂松近日&#xff0c;清华大学人工智能研究院常务副院长孙茂松教授亲手执笔&#xff0c;对自然语言处理的贡献、当前境界与未来挑战进行了深入的探讨。AI科技评论编辑组深有同感&#xff0c;认为此文十分值得一读&#xff0…

前端基础之jQuery

jQuery jQuery的思想&#xff0c;实际上很简单&#xff0c;八个字可以概括&#xff1a;选取元素&#xff0c;对其操作。 元素选取的表达式遵循 CSS 以及 XPath 的标准。选取结果可以是一个或多个&#xff0c;后面的操作针对所有被选取的元素。多个连续的操作可以用“链式”实现…

美国自动驾驶监管里程碑:新法规允许自动驾驶汽车取消方向盘

来源&#xff1a;AI前线编译&#xff1a;刘燕NHTSA 表示&#xff0c;这一新规迈出了“历史性”的一步&#xff0c;确保为配备自动驾驶系统的车辆的乘客保持同样高水平的乘员碰撞保护。这可以视为美国自动驾驶监管的一个里程碑。InfoQ 3 月 11 日消息&#xff0c;根据路透社的报…

DataTable实现分组

有时候我们从数据库中查询出来数据之后&#xff0c;需要按照DataTable的某列进行分组&#xff0c;可以使用下面的方法实现&#xff0c;代码如下&#xff1a; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using…

城市大脑的定义与理论基础综述

本文发表于2022年2月下旬的《中国建设信息化》&#xff0c;作者杜青峰 刘锋 任伟阳1 前言2015以来&#xff0c;城市大脑的概念和定义首次提出后。随着城市大脑领域在理论研究和产业实践上的探索和进展,城市大脑已经成为前沿科技领域和智慧城市建设领域的新热点,到2022年&…

线程实现模型

线程实现模型 线程实现模型主要分为&#xff1a;用户级线程模型&#xff0c;内核级线程模型和两级线程模型。他们的区别在于线程与内核线程之间的对应关系。 以下我们将分析这三种线程实现模型的特点&#xff1a; 用户级线程模型 &#xff08;1&#xff09;多对一关系 用户级线…

逆生长!小鼠「逆龄疗法」登Nature子刊,有望用于人类

来源&#xff1a;机器学习研究组订阅一种新的「逆龄疗法」在小鼠身上显示出希望的曙光&#xff01;最近&#xff0c;美国索尔克生物研究所的科学家运用细胞再生疗法&#xff0c;将「山中因子」注入小鼠&#xff0c;通过多组实验证明&#xff1a;仅数个月&#xff0c;小鼠年轻多…

消息中间件那些事--RabbitMQ

消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能&#xff0c;成为异步RPC的主要手段之一。当今市面上有很多主流的消息中间件&#xff0c;如老牌的ActiveMQ、RabbitMQ&#xff0c;炙手可热的Kafka&#xf…

中国联通李福昌:探索无线连接的未来

来源&#xff1a;C114通信网文&#xff1a;李福昌无线技术在当今社会中发挥着重要的作用&#xff0c;特别是5G商用以来&#xff0c;无线技术的应用从以个人为主扩展到面向生产和社会&#xff0c;逐步践行“5G改变社会”的目标。展望未来&#xff0c;面向6G&#xff0c;无线连接…

转载一个不错的LRU cache

https://github.com/paudley/lru_cache 转载于:https://www.cnblogs.com/water-bear/p/11511995.html

听完411头猪的哼哼,他们找到了理解“猪语”的算法 | Scientific Reports

图片来源&#xff1a;Pixabay来源 哥本哈根大学翻译 闭诗林编辑 魏潇我们现在可以解读猪的情绪了。一个国际研究小组利用猪从出生到死亡的生命过程中收集到的数千份录音&#xff0c;首次在其一生各个阶段的大量场景下&#xff0c;将猪的呼噜声转化为了真实的情绪。这项研究由…

弄懂goroutine调度原理

goroutine简介 golang语言作者Rob Pike说&#xff0c;“Goroutine是一个与其他goroutines 并发运行在同一地址空间的Go函数或方法。一个运行的程序由一个或更多个goroutine组成。它与线程、协程、进程等不同。它是一个goroutine“。 goroutine通过通道来通信&#xff0c;而协程…

JVM-类加载原理

写在前面 我们知道我们编写的java代码&#xff0c;会经过编译器编译成字节码文件&#xff08;class文件&#xff09;&#xff0c;再把字节码文件装载到JVM中&#xff0c;映射到各个内存区域中&#xff0c;我们的程序就可以在内存中运行了。那么字节码文件是怎样装载到JVM中的呢…

2022年斯坦福AI Index公布:中美主导跨国研究,专利、投资金额暴增

来源&#xff1a;学术头条当地时间 3 月 16 日&#xff0c;斯坦福大学以人为本人工智能研究所&#xff08;StanfordHAI&#xff09;正式发布了《2022 年人工智能指数报告》&#xff08;Artificial Intelligence Index Report 2022&#xff09;。这是该机构发布的第五份年度报告…

中国传感器规模将超7000亿元:2022最全面深入的产业分析

来源&#xff1a;前瞻经济学人整理&#xff1a;动感传感本文整理自前瞻经济学人的传感器产业报告&#xff0c;作为国内领先的咨询机构&#xff0c;前瞻经济学人的研报分析深度和数据丰富程度&#xff0c;都首屈一指。主要有如下几部分内容&#xff1a;•2022年中国传感器行业市…

强化学习教父Richard Sutton新论文探索决策智能体的通用模型:寻找跨学科共性...

来源&#xff1a;人工智能AI技术 论文虽然有些难懂&#xff0c;但或许是一个新的研究方向。强化学习和决策多学科&#xff08;Multi-Disciplinary Conference on Reinforcement Learning and Decision Making, RLDM&#xff09;的重要前提是&#xff0c;随着时间的推移&#xf…