概述
Spring PropertiesLoaderSupport是一个抽象基类,它抽象了从不同渠道加载属性的通用逻辑,以及这些属性应用优先级上的一些考虑。它所提供的这些功能主要供实现子类使用。Spring框架中,PropertiesLoaderSupport的实现子类有PropertiesFactoryBean,PropertyResourceConfigurer等。
首先,它将属性分成两类:本地属性(也叫缺省属性)和外来属性。这里本地属性指的是直接以Properties对象形式设置进来的属性。外来属性指的是通过外部资源形式设置进来需要加载的那些属性。
然后,对于本地属性和外来属性之间的的使用优先级,PropertiesLoaderSupport通过属性localOverride来标识。如果localOverride为false,表示外部属性优先级高,这也是缺省设置。如果localOverride为true,表示本地属性优先级高。
另外,PropertiesLoaderSupport还有一个属性fileEncoding用来表示从属性文件加载属性时使用的字符集。
PropertiesLoaderSupport 所在包 : org.springframework.core.io.support 。
源代码解析
属性定义
1 // 本地属性,通过设置Properties对象直接设置进来的属性 2 @Nullable 3 protected Properties[] localProperties; 4 5 // 本地属性和外来属性之间的优先级,或者叫做覆盖关系 6 // false 表示 外来属性优先级高于本地属性 (缺省值) 7 // true 表示 本地属性优先级高于外来属性 8 protected boolean localOverride = false; 9 10 // 外来属性对应资源,通过设置外部资源位置设置进来需要加载的属性 11 @Nullable 12 private Resource[] locations; 13 14 // 读取外来属性时遇到不存在的资源路径应该怎么办 ? 15 // false : 输出一个日志,然后继续执行其他逻辑 (缺省值) 16 // true : 抛出异常 17 private boolean ignoreResourceNotFound = false; 18 19 // 加载外来属性资源文件时使用的字符集 20 @Nullable 21 private String fileEncoding; 22 23 // 外来属性加载工具 24 private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
对于上述属性,PropertiesLoaderSupport
都提供了相应的set
方法。
主要功能方法
mergeProperties
合并本地属性和外来属性然后返回一个Properties
对象,这里面考虑了属性 localOverride
的应用。
1 /** 2 * Return a merged Properties instance containing both the 3 * loaded properties and properties set on this FactoryBean. 4 * 5 */ 6 protected Properties mergeProperties() throws IOException { 7 Properties result = new Properties(); 8 9 if (this.localOverride) { 10 // Load properties from file upfront, to let local properties override. 11 // localOverride == true, 先加载外来属性到结果对象 12 loadProperties(result); 13 } 14 15 if (this.localProperties != null) { 16 // 将本地属性合并到结果对象 17 for (Properties localProp : this.localProperties) { 18 CollectionUtils.mergePropertiesIntoMap(localProp, result); 19 } 20 } 21 22 if (!this.localOverride) { 23 // Load properties from file afterwards, to let those properties override. 24 // localOverride == false, 后加载外来属性到结果对象 25 loadProperties(result); 26 } 27 28 return result; 29 }
loadProperties
外部属性的加载方法。
1 /** 2 * Load properties into the given instance. 3 * @param props the Properties instance to load into 4 * @throws IOException in case of I/O errors 5 * @see #setLocations 6 */ 7 protected void loadProperties(Properties props) throws IOException { 8 if (this.locations != null) { 9 // 读取每一个属性文件资源 10 for (Resource location : this.locations) { 11 if (logger.isTraceEnabled()) { 12 logger.trace("Loading properties file from " + location); 13 } 14 try { 15 // 使用指定的字符集fileEncoding从外部资源路径location读取属性到props,使用的属性读取工具 16 // 是 propertiesPersister 17 PropertiesLoaderUtils.fillProperties( 18 props, new EncodedResource(location, this.fileEncoding), this.propertiesPersister); 19 } 20 catch (FileNotFoundException | UnknownHostException ex) { 21 // 出现异常时,如果ignoreResourceNotFound==true,则仅仅记录日志,继续读取下一个 22 // 资源文件,否则直接抛出该异常 23 if (this.ignoreResourceNotFound) { 24 if (logger.isDebugEnabled()) { 25 logger.debug("Properties resource not found: " + ex.getMessage()); 26 } 27 } 28 else { 29 throw ex; 30 } 31 } 32 } 33 } 34 }
总结
从上面分析可以看出,PropertiesLoaderSupport所实现的功能并不多,主要是设置要使用的本地属性和外部属性文件资源路径,最终通过mergeProperties方法将这些属性合并成一个Properties对象,本地属性和外部属性之间的优先级关系由属性localOverride决定。
————————————————
版权声明:本文为CSDN博主「安迪源文」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/andy_zhang2007/article/details/86749301