热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

springboot配置多个yml文件,springboot读取自定义yml文件

springboot配置多个yml文件,springboot读取自定义yml文件00-10101、序列2、加载自定义yml文件2.1、读取带@propertysource批注的ym

  springboot配置多个yml文件,springboot读取自定义yml文件

  00-1010 1、序列2、加载自定义yml文件2.1、读取带@ propertysource批注的yml配置文件-简单版2.2、读取带@ propertysource批注的yml配置文件-非简单版?2.3.前缀可行版本3,外部部署3.1,外部加载spring boot核心配置文件3.2,在@PropertySource中添加路径3.3,通过YamlPropertiesFactoryBean添加路径3.4,自定义yaml文件资源加载类。

  00-1010背景:有一个小项目需要背景。我是以Java Disruption为名拍的,被男票安利春装开机很疯狂,于是(被迫无所事事)开始了边开发边学习的道路.很好吃,信息量很大,而且超级好用!

  对于电厂项目,使用公司自己开发的实时数据库。后台涉及的很多测点的信息都需要存储在配置文件中(不要问我为什么不是关系数据库),希望部署时可以方便修改。考虑到内容比较多,放在application-pro.yml里确实不合适,所以我加了一个point.yml并不是因为现场测点信息会发生变化才需要更改。更有甚者,突然一拍脑袋,发现手在抖,写错了?

  首先,因为不小心变成了xxx.yml播放器,用的不错,但是回不去xxx.properties,传说官方不支持像xxx一样使用annotation @ property source( class path 3360 XXX . properties )加载yml配置文件。以下是如何加载自定义的yml文件。

  看一下官方说明

  关于加载自定义xxx.properties文件的方法,请参考本文:

  跳靴的性能配置分析

  注:我之前在找多数据源配置的数据的时候,因为数据对应的spring boot版本不同,很郁闷。请注意,我使用的版本是:

  弹簧靴2.13

  

目录

春开机资料很多,多到想都不用想就能解决问题,非常容易~项目做完之后冷静下来,我觉得还是要验证一下。毕竟打人家脸是为了以后出人头地。

 

  00-1010根据上面给出的官方公告,这条路是走不通的。因为没有看到文档对应的版本号,所以还是试试吧:

  #配置文件point . yml id 3360 2233 name 3360 Ellie(诶,这种信息为什么叫point?

  //配置相应的配置类@ data @ configuration @ property source(value={ class path : point . yml })@ configuration properties()public class test point { private int id;私有字符串名称;@ Override public String to String(){ return test point { id= id ,name= name }}}粘贴一个控制器进行测试。

  @RestControllerpublic类TestConfigController { @ Resource test point test point;@ApiOperation(测试配置文件)@ request mapping(value=/config )public resultbeanstalling test config(){ return resultbeanutil . makeokersep(test point . tostring());} }邮差,起来

  一切都好!

  所以如果只是想读取这么简单的信息,可以直接使用annotation @ propertysource。不知道官方不确定的影响是什么。

  00-1010添加一个列表基本类型看看。

  # point.ymlid: 2233na

  me: Elliecards: - XD02101263 - ZY8965 - GX0009 // 配置类 @Data@Configuration@PropertySource(value = {"classpath:point.yml"})@ConfigurationProperties()public class TestPoint { private int id; private String name; private List cards; @Override public String toString() { return "TestPoint{" + "id=" + id + ", name=" + name + + ", cards=" + cards + }; }}postman

  

 

  装逼失败,不行了哦。使用@Value("id")注解也是不行的呢,因为这个注解是用来匹配变量名称和配置文件不一致的情况。

  按照其他博客里讲的(才糊代码一个月根本没有深入看原理的我只好是:大佬说啥就是啥),是因为使用@PropertySource注解只能加载yml配置文件,但不能将其配置信息暴露给spring environment,需要手动暴露。方法就是在让application启动的时候把下面的bean加载。

  

@Beanpublic static PropertySourcesPlaceholderConfigurer properties() {PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();yaml.setResources(new ClassPathResource("point.yml"));configurer.setProperties(yaml.getObject());return configurer;}

偷懒的我直接丢到了main函数所在的.java文件。运行:

 

  

 

  真的不是我截错图哦。

  

 

  

2.3、加前缀可行版

毕竟我这么机智(无脑分析!),悄咪咪加了个前缀,前缀的名字随意取哈,与配置类中对应即可,我只是偷懒叫做prefix。

 

  

# point.ymlprefix: id: 2233 name: Ellie cards: - XD02101263 - ZY8965 - GX0009 // config类 @Data@Configuration@PropertySource(value = {"classpath:point.yml"})@ConfigurationProperties(prefix = "prefix") public class TestPoint { private int id; private String name; private List cards; @Override public String toString() { return "TestPoint{" + "id=" + id + ", name=" + name +  + ", cards=" + cards + }; }}

都挺好大结局?

 

  

 

  求助:

  这样为什么可行,俺是一点都不晓得的,如果有大佬路过,请帮忙解答!!!跪谢orz

  顺便说一句,出于好奇,试了下某些博文里说的前缀加yml分隔符---配合的方式,感觉上是一本正经胡说八道,实际上也没读出来。读取List<类>也是同样可行的。

  

# point.ymlprefix: id: 2233 name: Ellie cards: - name: XD code: XD02101263 - name: ZY code: ZY8965 - name: GX code: GX0009 // config 类@Data@Configuration@PropertySource(value = {"classpath:point.yml"})@ConfigurationProperties(prefix = "prefix")public class TestPoint { private int id; private String name; private List cards; @Override public String toString() { return "TestPoint{" + "id=" + id + ", name=" + name +  + ", cards=" + cards + }; }}// 并不需要有什么与众不同的card类@Datapublic class Card { private String name; private String code; @Override public String toString() { return "Card{" + "name=" + name +  + ", code=" + code +  + }; }}

请求

 

  

 

  查找资料的过程中还看到了一种别致的写法,是为了解决多层嵌套的yml的读写,未验证,因为有选择的话,我不愿意这样写,不过写法确实很别致,哈哈哈!https:///article/242026.htm

  

 

  

3、外部部署

其实就是把配置文件部署在jar包外部,方便修改而不必重新打包。

 

  

 

  

3.1、spring boot核心配置文件外部加载

希望外部加载自定义配置文件,需要先了解spring默认的文件加载方式。

 

  spring程序会按优先级从下面这些路径来加载application.properties配置文件:

  当前目录下的/config目录当前目录classpath里的/config目录classpath 根目录idea中,在源码下的classpath对应src/main/resources很明确,打包后的classpath在哪里俺是不知道的,然后就把打包后的jar包解压看了下,在BOOT-INFclasses下看到了application.yml和point.yml。所以要想覆盖配置文件,我再jar包同级目录下建了config文件夹,修改配置文件内容看覆盖是否生效。

  具体操作:

  打包的时候默认将application.yml和point.yml打包到jar中(classpath)部署时,jar包同级目录下建立config文件夹,修改application.yml中端口号和point.yml内容,看修改是否生效。修改后的point.yml文件如下:

  

prefix: id: 2233 name: FakeEllie cards: - name: NONE code: 00000001

测试结果:端口号修改生效(application.yml修改生效),修改后的point.yml并未生效。

 

  毕竟自定义配置文件,一厢情愿希望spring boot按照核心文件加载方式加载point.yml,没有生效也在意料之中,不过路并没有堵死。

  

 

  

3.2、在@PropertySource中添加路径

查资料的时候注意到还有这种写法:

 

  

@Data@Configuration@PropertySource(value = {"file:config/point.yml"})@ConfigurationProperties(prefix = "prefix")public class TestPoint { private int id; private String name; private List cards; @Override public String toString() { return "TestPoint{" + "id=" + id + ", name=" + name +  + ", cards=" + cards + }; }}

就是通过file来指定文件路径,之前是classpath来指定资源相对路径,说来神奇,这种方式没有报错,但读取的内容却是classpath下的point.yml,而不是config下的point.yml。

 

  想来是通过@ConfigurationProperties(prefix = "prefix")指定的前缀去classpath下匹配到的。跟@PropertySource(value = {"file:config/point.yml"})大概是没有关系了,忘崽牛奶真好喝。

  

 

  

3.3、通过YamlPropertiesFactoryBean添加路径

回想上面的描述,YamlPropertiesFactoryBean是将配置文件暴露给spring环境的,可以考虑使用它来指定文件路径。

 

  修改bean,添加new FileSystemResource("config/point.yml")来指定config文件夹下的配置。

  

@Beanpublic static PropertySourcesPlaceholderConfigurer properties() {PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();yaml.setResources(new ClassPathResource("point.yml"), new FileSystemResource("config/point.yml"));configurer.setProperties(yaml.getObject());return configurer;}

此时配置类上使用@PropertySource(value = {"file:config/point.yml"})这种写法,返回的是

 

  

 

  成功了?但是好像搞笑了。不过也说明了配置文件读取的顺序。config文件夹下的有最终决定权。

  为了直观些,俺顺手修改jar包同级目录下config文件夹中point.yml配置文件,保证list元素个数相同:

  

prefix: id: 2233 name: FakeEllie cards: - name: NONE code: 00000001 - name: NONE code: 00000002 - name: NONE code: 00000003

不搞笑了。

 

  

 

  但是,改成此时配置类上使用@PropertySource(value = {"classpath:point.yml"})后,返回并没有变化。所以YamlPropertiesFactoryBean将配置文件暴露给spring环境,说的应该就是将文件添加到spring的classpath下了,先读默认的,再读新添加这样子的。

  然鹅这样就没有办法在不进行外部配置的时候使用默认的classpath下的配置文件了。

  此外,通过YamlPropertiesFactoryBean添加配置文件的方式,就需要保证config/point.yml一定要存在,要想达到不进行外部配置的时候读取默认classpath下point.yml,在进行外部配置的时候读取config/point.yml。那就只好耍流氓了。

  

@Data@Configuration@PropertySource(value = {"file:config/point.yml", "classpath:point.yml"}, ignoreResourceNotFound = true)@ConfigurationProperties(prefix = "prefix")public class TestPoint { private int id; private String name; private List cards; @Override public String toString() { return "TestPoint{" + "id=" + id + ", name=" + name +  + ", cards=" + cards + }; }}

重点:然后!在不进行外部配置的时候,config/point.yml内容为空,或者干脆跟classpath下的point.yml内容保持一致。

 

  

小孩子才做选择题,我全都想要

 

  

虽然看上去像个意外,但是好在意啊啊啊啊,遏制不住的好奇心啊!就是刚刚那个拼起来的返回值。

 

  想看看是不是application.yml覆盖list也会这样,俺把配置类对应的内容举家搬迁到了application.yml中。如下:

  

// 配置类@Data@Configuration@ConfigurationProperties(prefix = "prefix")public class TestPoint { private int id; private String name; private List cards; @Override public String toString() { return "TestPoint{" + "id=" + id + ", name=" + name +  + ", cards=" + cards + }; }}

配置类默认读取application.yml。

 

  

# classpath:application.ymlprefix: id: 2233 name: Ellie cards: - name: XD code: XD02101263 - name: ZY code: ZY8965 - name: GX code: GX0009#config/application.ymlprefix: id: 2233 name: FakeEllie cards: - name: NONE code: 00000001

测试结果:

 

  

 

  并没有进行拼接啊喂!!!

  在各种调换顺序看影响的时候,修改了YamlPropertiesFactoryBean添加source的顺序,返回结果发生了变化。

  

@Beanpublic static PropertySourcesPlaceholderConfigurer properties() {PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();yaml.setResources(new FileSystemResource("config/point.yml"), new ClassPathResource("point.yml"));configurer.setProperties(yaml.getObject()); configurer.setIgnoreResourceNotFound(true);return configurer;}

返回结果

 

  

 

  有一种简单的在运行时通过命令参数指定配置文件的方式效果与此类似。

  

java -jar demo.jar --Dspring.config.location=point.yml

俺的原则时,代码能解决的,就不要交给人来解决。

 

  虽然没有解决任何问题,但是顺便知道了读取的先后顺序就是setResources的先后顺序。卒

  

所以目前的结论是,对于有list的配置,并且个数发生变化的时候,这种方式并不适用。

 

  

 

  

3.4、自定义yaml文件资源加载类

在注解@PropertySource中,有个属性factory主要用来声明解析配置文件的类,这个类必须是PropertySourceFactory接口的实现。从这里入手。

 

  

 

  参考资料:

  Spring Boot自定义加载yml实现,附源码解读

  默认调用的是PropertySourceFactory的实现DefaultPropertySourceFactory,因此可以自定义factory实现PropertySourceFactory接口,也可以扩展DefaultPropertySourceFactory类。两种写法的效果是一样的,列出来。

  直接实现PropertySourceFactory接口

  

public class YamlPropertyLoaderFactory implements PropertySourceFactory { @Override public PropertySource createPropertySource(String name, EncodedResource encodedResource) throws IOException { List> sources = name != null ? new YamlPropertySourceLoader().load(name, encodedResource.getResource()) : new YamlPropertySourceLoader().load( getNameForResource(encodedResource.getResource()), encodedResource.getResource()); if (sources.size() == 0) { return null; } return sources.get(0); } private static String getNameForResource(Resource resource) { String name = resource.getDescription(); if (!StringUtils.hasText(name)) { name = resource.getClass().getSimpleName() + "@" + System.identityHashCode(resource); } return name; }}

扩展DefaultPropertySourceFactory

 

  

 public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory { @Override public PropertySource createPropertySource(String name, EncodedResource resource) throws IOException { if (resource == null) { return super.createPropertySource(name, resource); } List> sources = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource()); if (sources.size() == 0) { return super.createPropertySource(name, resource); } return sources.get(0); }}

建议用第二种方式。

 

  用factory的方式来实现的话,前面莫名其妙加个prefix就可以正常读取的诡异操作也不需要了哦。

  使用方式如下:

  

@Data@Configuration@PropertySource(value = {"classpath:point.yml", "file:config/point.yml"}, factory = YamlPropertyLoaderFactory.class, ignoreResourceNotFound = true)@ConfigurationPropertiespublic class TestPoint{ private int id; private String name; private List cards; @Override public String toString() { return "TestPoint{" + "id=" + id + ", name=" + name +  + ", cards=" + cards + }; }}# config/point.ymlid: 2233name: FakeElliecards: - name: NONE code: 00000001

测试结果:

 

  

 

  自定义factory的方式,读取多种路径的配置文件时,也是有先后顺序的,就是@PropertySource中value属性指定的顺序,与使用YamlPropertiesFactoryBean将资源暴露给spring环境不同,这个不会有前面出现的拼接效果出现,棒呆~

  以解决问题为目标和以写清楚文章为目标去看同样的问题,真的是不一样的探索路径呢,凑字数和为了flag不倒的文写的远远超出自己最初的预期,真好,超喜欢!

  以上为个人经验,希望能给大家一个参考,也希望大家多多支持盛行IT。



推荐阅读
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
author-avatar
曾军78930
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有