系统中访问properties文件中定义的配置项是很常见的需求,jdk提供java.util.Properties类加载指定的配置文件(当然不一定从本地文件、任意来源的流对象也可以)。

在一个大型系统中,我们有可能需要定义多个配置文件,如果每个文件都需要声明一个Properties与之对应,那么代码会显得很啰嗦。

方法一:统一写一个加载工具类,可以,但是不见得最好。
方法二:借助spring framework中的Envioment对象和@PropertySource属性

以下是一段实例代码,定义一个ApplicationConfig类,内部封装了 envioment对象,然后通过envioment获取属性。

@Component
public class ApplicationConfig {@Autowired(required = false)private Environment environment;/*** 获取指定key对应的string值,key不存在会抛出异常* * @param key* @return*/public String getString(String key) {String val = internalGet(key);if (val == null) {throw new RuntimeException("key:" + key + " not exist!");}return val;}/*** 获取指定key对应的string值,如果key不存在则返回defaultVal* * @param key* @param defaultVal* @return*/public String getString(String key, String defaultVal) {String val = internalGet(key);if (val == null) {return defaultVal;} else {return val;}}protected String internalGet(String key) {return this.environment != null ? this.environment.getProperty(key): System.getProperty(key);}
除了getString,getInteger、getBoolean也可以由这个类统一处理,方便外部调用。

如果environment被正确注入,那么我们就可以统一从中获取“所有属性”。

什么是"所有属性"?
很多,说些常见的:

  1. 系统启动时参数,即 -Dkey=value 方式定义的;
  2. 系统属性,即System.getProperty(String key);
  3. 环境变量
  4. 容器内置的一些属性,比如springboot启动时,应用上文参数、application.properties、bootstrap.properties等,这些特定的容器也会把自身的一些属性加入到environment中
  5. spting cloud config(分布式配置管理框架)的客户端会将服务器抓取的配置放到environment中
  6. 本地属性文件,当然需要通过某种方式加载进去(别急,下文会说)

当然,还有很多属性来源,不一一列举了。

我们的重点是,有了environment,我们可以通过它读取所有需要加载的属性文件了,算是一个统一的读取入口。

那么如何方便加载配置文件呢?那就要借助@PropertySource注解了。

@Component
@PropertySource(value = "classpath:myconfig.properties", ignoreResourceNotFound = true)
public class MyConfig {@Value("${key1:value1}")private String key1;@Value("${key2:value2}")private String key2;public String getKey1() {return key1;}public String getKey2() {return key2;}
}

我们定义一个Bean:MyConfig(我们可以通过很多方式定义bean,但不管什么方式,一定要确保MyConfig可以被springIOC加载),由于它被添加了@PropertySource注解,指定了属性文件的位置,那么spring就会尝试加载这个文件,并最终添加到environment中。

ignoreResourceNotFound属性意思是,如果文件不存在,就忽略,否则会抛异常,所以如果这个文件不是必须的,就设置成true.
本人也建议设置true,按照约定大于配置的原则,我们可以在代码段处理默认值。

那么如何处理默认值呢?

一,如果通过envioment获取,可以调用String getString(String key, String defaultVal)方法,外部传入默认值;

二,通过@Value注解
@Value("${key1:value1}")意思是,spring会从environment中获取key1的值,添加到key1字段中。
需要注意的是:只要environment中存在key1即可,也就是说,key1可以通过其他方式添加,不一定需要定义在myconfig.properties中;另外,所有environment的属性就可以用这样的方式注入到任何bean的字段中。
还有一点,如果environment中不存在key1,那么麻烦了,就会出错,所以key1:后面的value1就是默认值,通过这样的方式避免出错,也定义了默认值。

加载PropertySource的spring源代码在org.springframework.context.annotation.ConfigurationClassParser类中,我贴一下代码

private void processPropertySource(AnnotationAttributes propertySource) throws IOException {String name = propertySource.getString("name");if (!StringUtils.hasLength(name)) {name = null;}String encoding = propertySource.getString("encoding");if (!StringUtils.hasLength(encoding)) {encoding = null;}String[] locations = propertySource.getStringArray("value");Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));for (String location : locations) {try {String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);Resource resource = this.resourceLoader.getResource(resolvedLocation);addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));}catch (IllegalArgumentException | FileNotFoundException | UnknownHostException ex) {// Placeholders not resolvable or resource not found when trying to open itif (ignoreResourceNotFound) {if (logger.isInfoEnabled()) {logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());}}else {throw ex;}}}}

大家可以明显看到,ignoreResourceNotFound属性就在catch代码块里起作用了。

最后说明下优先级:
系统启动参数>application.properties参数(如果是springboot程序)>自定义文件参数>默认值。

以下是调试代码的截图

大家可以看到 myconfig文件对应的properysource在第9个,系统参数在第5个,而springboot的application.properties定义的参数是第7个,它们优先级都比myconfig要高。

以上就是pieces框架如何加载属性文件和访问属性的介绍,如果配置项是从springcloudconfig服务端获取的话,那么就不适合用@PropertySource的方式了,这个以后有机会再详细说明。

Pisces的属性配置文件加载相关推荐

  1. Spring使用环境变量控制配置文件加载(转)

    项目中需要用到很多配置文件,不同环境的配置文件是不一样的,因此如果只用一个配置文件,势必会造成配置文件混乱,这里提供一种利用环境变量控制配置文件加载的方法,如下: 一.配置环境变量 如果是window ...

  2. 配置文件加载位置||外部配置加载顺序||自动配置原理

    配置文件加载位置 SpringBoot会从这四个位置全部加载主配置文件:互补配置: 外部配置加载顺序 自动配置原理 1.自动配置原理: 1).SpringBoot启动的时候加载主配置类,开启了自动配置 ...

  3. 异常信息配置文件已被另一个程序更改_抢先目睹:SpringBoot2.4配置文件加载机制大变化

    翻译: 冷冷.如梦技术 原文链接:spring.io/blog/2020/0- Spring Boot 2.4.0.M2 刚刚发布,它对 application.properties 和 applic ...

  4. hadoop配置文件加载机制

    hadoop配置文件加载机制 @(HADOOP)[hadoop] hadoop通过Configuration类来保存配置信息 1.通过Configuration.addResource()来加载配置文 ...

  5. SpringBoot - 配置文件加载位置与优先级

    SpringBoot - 配置文件加载位置与优先级 [1]项目内部配置文件 spring boot 启动会扫描以下位置的application.properties或者application.yml文 ...

  6. springboot配置文件加载顺序_「SpringBoot系列」配置文件加载优先级解析

    SpringBoot提供了外部分配置功能,可以使用属性文件(properties).YAML(yml)文件.环境变量和命令行参数来进行处部参数配置,并t以特定的顺序来处理配置,以便于允许合理的覆盖值. ...

  7. Mybatis 源码分析(一)配置文件加载流程

    Mybatis 源码分析(一)配置文件加载流程 1.项目构建 引入依赖 <dependency><groupId>org.mybatis</groupId>< ...

  8. 计算机安全权限不足或配置文件损坏,配置文件加载失败 - Windows Server | Microsoft Docs...

    在桌面设置期间发生错误,并且首次登录 Windows 时桌面位置不可用 09/08/2020 本文内容 本文可帮助解决将 ntuser.dat 或 usrclass.dat 文件定义为只读,或者配置文 ...

  9. springBoot配置文件加载原理探究

    尽管用springBoot做开发已经有很长一段时间了,在开发时一般都是直接将application.properties或application.yml,放在开发环境的resources下的,运行起来 ...

  10. Spring Boot 配置文件加载顺序

    1.介绍 依次为: bootstrap.properties -> bootstrap.yml -> application.properties -> application.ym ...

最新文章

  1. 南方电网两栖机器人_探访国内最大5G智能电网应用区:5G机器人已替代人工巡检...
  2. Matlab直线一级倒立摆控制方法研究
  3. Windows Phone 的控件倾斜效果
  4. Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency
  5. .NET技术之美-网络编程
  6. SAP UI5 why failed to load 'sap/cus/crm/lib/reuse/library.js' from resources/sap/cus/crm
  7. oracle实时分析,Oracle Exalytics 大幅提升实时分析洞察力
  8. hdu 1398 Square Coins/hdu 1028 Ignatius and the Princess III
  9. HDFS进阶应用 配置 NFS 网关
  10. 基础工具类Joiner的使用
  11. Day 3 (云计算-zsn)
  12. dedecms 栏目绑定二级域名
  13. 一些开源代码网站介绍(持续添加中....)
  14. 2020煤矿安全监测监控证考试及煤矿安全监测监控模拟考试题库
  15. 氨基/请加/羧基/生物素功能化水溶性CdSeQds,CdTeQds,CdSe/ZnSQds,ZnOQds,CuInS/ZnSQds量子点
  16. notepad++的下载及安装HEX-Editor插件
  17. keil集成环境c语言总结,Keil C51单片机集成开发环境编程与调试教程
  18. 2021年中国程序员薪资和生活现状调查报告
  19. FileZilla Server 0.9.43 中文版 安装教程
  20. Python爬取磁力链信息

热门文章

  1. 什么是跳跃表。跳跃表的原理及其实现。
  2. Windows权限维持方法
  3. Python个人快速入门学习(九)jieba库的使用
  4. 在杭州云栖大会,我们看到了一个新的阿里巴巴
  5. 搜站 - 聚合搜索,一站访问
  6. win8.1产品安装临时密钥
  7. Aspose Word模板使用总结
  8. cocos 添加遮罩后白屏_Cocos2dx3.2 Crazy Tetris 由于遮罩引起的部分手机白屏
  9. 实战Nagios网络监控(2)—— Nagios+Nrpe监控其他主机
  10. 51单片机实验 7段数码管静态显示数字