`

动态加载配置文件类,通用类

    博客分类:
  • Java
阅读更多
package config;

import java.io.File;
import java.io.FilenameFilter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.EnvironmentConfiguration;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.SystemConfiguration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;


/**
 * 动态加载配置文件类
 * <pre>
 * 默认为动态加载配置,当然你也可以指定autoReload=false不动态更新配置
 * 配置信息来源:
 * 1.JVM启动参数
 * 2.系统环境变量
 * 3.classpath下面的.properties配置文件(没有在JVM启动参数中配置-Dglobal.config.path="配置分离目录"时的加载策略)
 * 4.global.config.path(配置分离目录)下面的所有的.properties配置文件(注:需要在JVM启动参数中配置-Dglobal.config.path="配置分离目录")
 * 5.${global.config.path}/${appConfigPath}下面的所有的.properties配置文件(注:需要在JVM启动参数中配置-Dglobal.config.path="配置分离目录"和传入appConfigPath参数)
 * 6.${global.config.path}/${appConfigPath}下面特定的.properties配置文件(注:需要在JVM启动参数中配置-Dglobal.config.path="配置分离目录"和传入appConfigPath参数、configFiles配置文件列表(多个配置文件用,分隔))
 * 说明:1,2是自动加入的,无需配置. 3与4,5,6是互斥的,当没有在JVM启动参数中配置-Dglobal.config.path="配置分离目录"时,就使用3,反之就用4,5,6而不会加载classpath下面的配置文件
 * </pre>
 * <strong>使用方法</strong>
 * <pre>
 * eg:创建一个自动动态加载${global.config.path}/openapi-service/目录下面的mail.properties,common.properties,sysConfig.properties配置文件的对象
 * PropertyPlaceholderConfigurer config = PropertyPlaceholderConfigurer.getBuilder().autoReload(true).appConfigPath("openapi-service").configFiles("mail.properties,common.properties").configFiles(new String [] {"sysConfig.properties"}).build();
 * </pre>
 * <strong>lib依赖</strong>
 * @since commons-configuration 1.8
 * @since commons-lang 2.6
 * @author zhangjiawei 2012-7-20
 *
 */
public final class PropertyPlaceholderConfigurer {
	
	/**配置分离基目录**/
	private static final String BASE_PATH;
	
	/**应用程序在配置分离下面的子目录**/
	private String appConfigPath = "";
	
	/**要加载的配置文件,多个配置文件用,分隔,不写则加载目录下面的所有.properties文件**/
	private String [] configFiles;
	
	/**自动动态加载,默认为true**/
	private boolean autoReload = true;
	
	/**properties文件配置项**/
	private final CompositeConfiguration  props = new CompositeConfiguration();
	
	/**配置文件对应的PropertiesConfiguration列表**/
	private List<PropertiesConfiguration> propList = new ArrayList<PropertiesConfiguration>(10);
	
	/**全局配置分离参数**/
	private static final String GLOBAL_CONFIG_PATH = "global.config.path";
	
	static{
		/**JVM启动参数配置***/
		SystemConfiguration sysConfig = new SystemConfiguration();
		String globalPath = sysConfig.getString(GLOBAL_CONFIG_PATH);
		if(StringUtils.isBlank(globalPath)){/**默认加载classpath下面的文件**/
			globalPath = Thread.currentThread().getContextClassLoader().getResource("").getFile();
		}
		BASE_PATH = globalPath;
	}

	/**
	 * 实例完成对象后,初始化操作
	 */
	private void init(){
		/**加入配置JVM的启动参数**/
		props.addConfiguration(new SystemConfiguration());
		/**加入环境变更参数**/
		props.addConfiguration(new EnvironmentConfiguration());
	}
	
	
	/**
	 * 加载默认的配置文件:
	 * 如果加了启动参数:global.config.path,就会加载global.config.path下面所有的.properties配置文件
	 * 如果没有,就加载classpath下面所有的.properties配置文件
	 * @throws ConfigurationException
	 */
	private PropertyPlaceholderConfigurer() throws ConfigurationException{
		this(true,null,"");
	}
	
	/**
	 * 加载默认的配置文件:
	 * 如果加了启动参数:global.config.path,就会加载global.config.path下面所有的.properties配置文件
	 * 如果没有,就加载classpath下面所有的.properties配置文件
	 * @param autoReload	自动动态加载
	 * @throws ConfigurationException 
	 */
	private PropertyPlaceholderConfigurer(boolean autoReload) throws ConfigurationException{
		this(autoReload,null,"");
	}
	
	/**
	 * 加载appConfigPath目录下面的所有的.properties配置文件
	 * 加载原理:
	 * 如果加了启动参数:global.config.path,就会加载${global.config.path}/appConfigPath 下面所有的.properties配置文件
	 * 如果没有,就加载${classpath}/appConfigPath下面所有的.properties配置文件
	 * @param autoReload	自动动态加载
	 * @param appConfigPath	应用的配置目录
	 * @throws ConfigurationException 
	 */
	private PropertyPlaceholderConfigurer(boolean autoReload,String appConfigPath) throws ConfigurationException{
		this(autoReload,appConfigPath,"");
	}
	
	
	/**
	 * 加载appConfigPath目录下面的所有的.properties配置文件
	 * 加载原理:
	 * 如果加了启动参数:global.config.path,就会加载${global.config.path}/appConfigPath 下面所有的.properties配置文件
	 * 如果没有,就加载${classpath}/appConfigPath下面所有的.properties配置文件
	 * @param appConfigPath	应用的配置目录
	 * @throws ConfigurationException 
	 */
	private PropertyPlaceholderConfigurer(String appConfigPath) throws ConfigurationException{
		this(true,appConfigPath,"");
	}
	
	/**
	 * 加载appConfigPath目录下面指定的configFiles配置文件(多个配置文件用,分隔)
	 * 加载原理:
	 * 如果加了启动参数:global.config.path,就会加载${global.config.path}/appConfigPath下面configFiles里面的配置文件
	 * 如果没有,就加载${classpath}/appConfigPath下面所有的configFiles里面的配置文件
	 * @param autoReload	自动动态加载
	 * @param appConfigPath	应用的配置目录
	 * @param configFiles	多个配置文件用,分隔
	 * @throws ConfigurationException 
	 */
	private PropertyPlaceholderConfigurer(boolean autoReload,String appConfigPath,String configFiles) throws ConfigurationException{
		this(true,appConfigPath,StringUtils.split(configFiles, ","));
	}
	
	/**
	 * 加载appConfigPath目录下面指定的configFiles配置文件(多个配置文件用,分隔)
	 * 加载原理:
	 * 如果加了启动参数:global.config.path,就会加载${global.config.path}/appConfigPath下面configFiles[]里面的配置文件
	 * 如果没有,就加载${classpath}/appConfigPath下面所有的configFiles[]里面的配置文件
	 * @param appConfigPath	应用的配置目录
	 * @param configFiles	配置文件数组
	 * @throws ConfigurationException
	 */
	private PropertyPlaceholderConfigurer(String appConfigPath,String [] configFiles) throws ConfigurationException{
		this(true,appConfigPath,configFiles);
	}
	
	
	/**
	 * 加载appConfigPath目录下面指定的configFiles配置文件(多个配置文件用,分隔)
	 * 加载原理:
	 * 如果加了启动参数:global.config.path,就会加载${global.config.path}/appConfigPath下面configFiles[]里面的配置文件
	 * 如果没有,就加载${classpath}/appConfigPath下面所有的configFiles[]里面的配置文件
	 * @param autoReload	自动动态加载
	 * @param appConfigPath	应用的配置目录
	 * @param configFiles	配置文件数组
	 * @throws ConfigurationException
	 */
	private PropertyPlaceholderConfigurer(boolean autoReload,String appConfigPath,String [] configFiles) throws ConfigurationException{
		this.autoReload = autoReload;
		this.appConfigPath = appConfigPath;
		this.configFiles = configFiles;
		init();/**完成初始化的一些相关操作**/
		loadConfigFiles();
	}
	
	
	/**
	 * 加载配置文件
	 * @throws ConfigurationException
	 */
	private void loadConfigFiles() throws ConfigurationException{
		
		String basePath = BASE_PATH + File.separator + appConfigPath;
		/**如果没有写配置文件,则加载目录下面所有的.properties文件**/
		if(ArrayUtils.isEmpty(configFiles)){
			File  confDirFile = null;
			if(StringUtils.isBlank(appConfigPath)){
				confDirFile = new File(BASE_PATH);
			}else{
				confDirFile = new File(BASE_PATH, appConfigPath);
			}
			if (!confDirFile.exists()){
				throw new RuntimeException("Config directory <" + confDirFile.getAbsolutePath() + "> doesn't exists.");
			}
			/**文件名**/
			String[] files = confDirFile.list(new FilenameFilter() {
				@Override
				public boolean accept(File dir, String name) {
					if (!name.endsWith(".properties")) {
						return false;
					}
					if (name.equals("log4j.properties")) {/**过滤掉log4j的配置文件**/
						return false;
					}
					return true;
				}
			});
			for(String file : files){
				PropertiesConfiguration prop = new PropertiesConfiguration();
				prop.setBasePath(basePath);
				prop.setFileName(file);
				prop.setAutoSave(false);
				if(autoReload){/**重载策略,5秒钟监视文件变化***/
					prop.setReloadingStrategy(new FileChangedReloadingStrategy());
				}
				prop.load();/**加载配置**/
				propList.add(prop);
				props.addConfiguration(prop);
			}
		}else{
			for(String file : configFiles){
				PropertiesConfiguration prop = new PropertiesConfiguration();
				prop.setBasePath(basePath);
				prop.setFileName(file);
				prop.setAutoSave(false);
				if(autoReload){/**重载策略,5秒钟监视文件变化***/
					prop.setReloadingStrategy(new FileChangedReloadingStrategy());
				}
				prop.load();/**加载配置**/
				propList.add(prop);
				props.addConfiguration(prop);
			}
		}
	}
	
	
	
	public String getAppConfigPath() {
		return appConfigPath;
	}

	public boolean isAutoReload() {
		return autoReload;
	}

	/**
	 * 获取配置项(返回结果为String)
	 * @param key
	 * @return
	 */
	public String getProperty(String key){
		return StringUtils.trim(props.getString(key));
	}
	
	/**
	 * 获取Boolean类型的配置项
	 * 注:无该配置荐时,返回false
	 * @param key
	 * @return
	 */
	public Boolean getBooleanProperty(String key){
		return props.getBoolean(key,false);
	}
	
	
	/**
	 * 获取Integer类型的配置项
	 * 注:无该配置荐时,返回new Integer(0)
	 * @param key
	 * @return
	 */
	public Integer getIntegerProperty(String key){
		return props.getInteger(key, new Integer(0));
	}
	
	
	/**
	 * 获取Integer类型的配置项
	 * 注:无该配置荐时,返回new Float(0)
	 * @param key
	 * @return
	 */
	public Float getFloatProperty(String key){
		return props.getFloat(key, new Float(0));
	}
	
	
	/**
	 * 获取Long类型的配置项
	 * 注:无该配置荐时,返回new Long(0)
	 * @param key
	 * @return
	 */
	public Long getLongProperty(String key){
		return props.getLong(key, new Long(0));
	}
	
	
	/**
	 * 获取Double类型的配置项
	 * 注:无该配置荐时,返回new Double(0)
	 * @param key
	 * @return
	 */
	public Double getDoubleProperty(String key){
		return props.getDouble(key, new Double(0));
	}
	
	
	/**
	 * 获取Short类型的配置项
	 * 注:无该配置荐时,返回new Short(0)
	 * @param key
	 * @return
	 */
	public Short getShortProperty(String key){
		return props.getShort(key, Short.valueOf("0"));
	}
	
	
	/**
	 * 获取String []类型的配置项
	 * 注:配置项各字符之前通过,分隔 eg param =a,b,c,d
	 * @param key
	 * @return
	 */
	public String [] getStringArrayProperty(String key){
		return 	props.getStringArray(key);
	}
	
	
	
	
	/**
	 * 获取BigDecimal类型的配置项
	 * 注:无该配置荐时,返回new BigDecimal("0")
	 * @param key
	 * @return
	 */
	public BigDecimal getBigDecimalProperty(String key){
		return props.getBigDecimal(key, new BigDecimal("0"));
	}
	
	
	/**
	 * 重新加载配置项
	 */
	public void reloadProperties(){
		for(PropertiesConfiguration prop : propList){
			prop.reload();
		}
	}
	
	/**
	 * 刷新配置项
	 * @throws ConfigurationException 
	 */
	public void refreshProperties() throws ConfigurationException {
		for(PropertiesConfiguration prop : propList){
			prop.refresh();
		}
	}
	
	
	
	/**
	 * 返回构建 PropertyPlaceholderConfigurer(动态加载配置文件)的Builder
	 * @return
	 */
	public static PropertyPlaceholderBuilder getBuilder(){
		return new PropertyPlaceholderBuilder();
	}
	
	/**
	 * 构建 PropertyPlaceholderConfigurer(动态加载配置文件)
	 * PropertyPlaceholderConfigurer这个类参数比较多,固使用Builder模式
	 * @author zhangjiawei
	 *
	 */
	public static class PropertyPlaceholderBuilder{
		
		/**应用程序在配置分离下面的子目录**/
		private String appConfigPath = "";
		
		/**要加载的配置文件,多个配置文件用,分隔,不写则加载目录下面的所有.properties文件**/
		private String [] configFiles;
		
		/**自动动态加载,默认为true**/
		private boolean autoReload = true;
		
		/**
		 * 设置应用的配置目录
		 * @param appConfigPath 应用的配置目录
		 */
		public PropertyPlaceholderBuilder appConfigPath(String appConfigPath){
			this.appConfigPath = appConfigPath;
			return this;
		}
		
		/**
		 * 设置是否自动动态加载
		 * @param autoReload 自动动态加载
		 */
		public PropertyPlaceholderBuilder autoReload(boolean autoReload){
			this.autoReload = autoReload;
			return this;
		}
		
		/**
		 * 设置配置文件,多个配置文件用,分隔
		 * @param configFiles
		 */
		public PropertyPlaceholderBuilder configFiles(String configFiles){
			this.configFiles = addConfigFiles(StringUtils.split(configFiles, ","));
			return this;
		}
		
		/**
		 * 设置配置文件数组
		 * @param configFiles
		 */
		public PropertyPlaceholderBuilder configFiles(String [] configFiles){
			this.configFiles = addConfigFiles(configFiles);
			return this;
		}
		
		/**
		 * 添加配置文件
		 * @param configFiles
		 * @return
		 */
		private String [] addConfigFiles(String [] configFiles){
			if(this.configFiles != null && configFiles != null && configFiles.length>0){
				return (String[]) ArrayUtils.addAll(this.configFiles, configFiles);
			}else{
				return this.configFiles;
			}
		}
		
		/**
		 * 生成PropertyPlaceholderConfigurer对象
		 * @return
		 * @throws ConfigurationException 
		 */
		public PropertyPlaceholderConfigurer build() throws ConfigurationException{
			return  new PropertyPlaceholderConfigurer(autoReload, appConfigPath,configFiles);
		}
	}
	
	
	/******************  main test ****************************/
	
	public static void main(String[] args) {
		try {
			PropertyPlaceholderConfigurer conf = new PropertyPlaceholderConfigurer();
			System.out.println(PropertyPlaceholderConfigurer.BASE_PATH);
			
			
			conf = PropertyPlaceholderConfigurer.getBuilder().autoReload(true).appConfigPath("openapi-service").configFiles("mail.properties,common.properties").configFiles(new String [] {"sysConfig.properties"}).build();
			
			/**
			 * 
			 * -Dglobal.config.path="D:\eclipse\workspace\openapi-service\env\test"
			 *
			 **/
//			conf = new PropertyPlaceholderConfigurer(true,"openapi-service");
//			
//			conf.getAppConfigPath();
//			
//			conf = new PropertyPlaceholderConfigurer(true,"openapi-service",new String []{"cod_support_rule.properties","common.properties"});
//			
//			conf.getAppConfigPath();
			
			while(true){
				System.out.println(conf.getProperty("mail.reconciliation.smtp.auth"));
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
			
		} catch (ConfigurationException e) {
			e.printStackTrace();
		}
		
	}
	
	
	
}


分享到:
评论

相关推荐

    python入门-30.寻找列表中只出现一次的数字-寻找单身狗.py

    python入门-30.寻找列表中只出现一次的数字——寻找单身狗.py

    布尔教育linux优化笔记

    linux优化笔记,配套视频:https://www.bilibili.com/list/474327672?sid=4496133&spm_id_from=333.999.0.0&desc=1

    知识付费系统-直播+讲师入驻+课程售卖+商城系统-v2.1.9版本搭建以及资源分享下载

    知识付费系统-直播+讲师入驻+课程售卖+商城系统-v2.1.9版本搭建以及资源分享下载,CRMEB知识付费分销与直播营销系统是由西安众邦科技自主开发的一款在线教育平台,该系统不仅拥有独立的知识产权,还采用了先进的ThinkPhp5.0框架和Vue前端技术栈,集成了在线直播教学及课程分销等多种功能,旨在为用户提供全方位的学习体验,默认解压密码youyacaocom

    美妆神域-JAVA-基于springBoot美妆神域设计与实现

    美妆神域-JAVA-基于springBoot美妆神域设计与实现

    原生js制作Google粘土logo动画涂鸦代码.zip

    原生js制作Google粘土logo动画涂鸦代码.zip

    golin 扫描工具使用, 检查系统漏洞、web程序漏洞

    golin 扫描工具使用, 检查系统漏洞、web程序漏洞

    原生态纯js图片网格鼠标悬停放大显示特效代码下载.zip

    原生态纯js图片网格鼠标悬停放大显示特效代码下载.zip

    用AWLUM进行灰色编码2^2n-QAM调制的精确率Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    去水印web端独立版web

    去水印web端独立版web

    原生js制作左侧浮动可折叠在线客服代码.zip

    原生js制作左侧浮动可折叠在线客服代码.zip

    Chrome 谷歌浏览器下载

    Chrome 谷歌浏览器下载

    亲测全新完整版H5商城系统源码 附教程

    全新完整版H5商城系统源码 自己花钱买的,亲测可用,需要自行下载 H5商城系统设置是实现商城基本功能的核心部分,涵盖了从网站配置、短信和支付配置,到商品、工单、订单、分站和提现管理等多个模块的设置。以下是详细的设置指南,帮助您快速上手并高效管理商城系统。 测试环境:Nginx+PHP7.0+MySQL5.6 1. 网站配置 设置商城名称、LOGO、标题、联系方式和SEO关键词等,确保商城专业和易于搜索。 2. 短信配置 配置短信接口和模板,用于发送订单通知、验证码等,提升用户体验。 3. 支付接口配置 配置微信、支付宝等支付接口,填写API密钥和回调地址,确保支付流畅。 4. 商品分类管理 对商品进行分类和排序,设置分类名称和图标,便于用户查找商品。 5. 商品管理 添加和管理商品信息、规格、图片等,确保商品信息准确丰富。 6. 工单管理 查看和回复用户工单,记录售后问题,提升用户服务质量。 7. 订单管理 查看订单详情,更新订单状态,支持批量导出,方便订单跟踪。 8. 分站管理 创建不同区域分站,设置权限,统一管理各区域市场。 9. 提现管理

    短信3.141592672893982398674234

    apk安装包

    原生js选项卡插件自定义图片滑动选项卡切换.zip

    原生js选项卡插件自定义图片滑动选项卡切换.zip

    1-宗教信息佛教佛寺寺庙庵堂相关数据-社科数据.zip

    宗教信息佛教佛寺寺庙庵堂相关数据集提供了全国各个地区省市县各个佛教寺庙的详细信息。这些数据不仅包括寺庙的名称和负责人姓名,还涵盖了所属省份、地级市、区县、具体地址、建立日期以及支派类别等关键信息。该数据集整理了超过3万条样本,为研究中国佛教寺庙的分布、历史和文化提供了丰富的第一手资料。这些信息有助于了解佛教在中国的传播和发展,以及寺庙在社会和文化中的作用。数据的整理和提供,对于宗教学、社会学、历史学和文化研究等领域的学者来说,是一个宝贵的资源。

    线性电阻网络的等效电阻计算Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    简单的 Python 版本管理.zip

    简单的 Python 版本管理pyenvpyenv 可让您轻松在多个 Python 版本之间切换。它简单、不引人注目,并遵循 UNIX 传统,即使用单一用途的工具来做好一件事。该项目由rbenv和 ruby​​-build分叉而来,并针对 Python 进行了修改。pyenv 的作用是什么......允许您根据每个用户更改全局 Python 版本。为每个项目的 Python 版本提供支持。允许您使用环境变量覆盖 Python 版本。一次搜索多个 Python 版本的命令。这可能有助于使用tox跨 Python 版本进行测试。与 pythonbrew 和 pythonz 相比,pyenv没有……依赖于Python本身。pyenv由纯shell脚本制作。不存在Python的引导问题。需要加载到你的 shell 中。相反,pyenv 的 shim 方法通过向你的 中添加目录来工作PATH。管理虚拟环境。当然,你可以自己创建虚拟环境 ,或者使用pyenv-virtualenv 来自动化该过程。目录安装获取 PyenvLinux/UNIX自动安装程序基本

    Notepad-v2.20工具,是替代Notepad++的首选工具

    Notepad-v2.20工具,是替代Notepad++的首选工具

    原生js随机图片拖拽排序代码.zip

    原生js随机图片拖拽排序代码.zip

    更快、更好、更稳定的Redis桌面(GUI)管理客户端,兼容Windows、Mac、Linux,性能出众,轻松加载海量键值

    更快、更好、更稳定的Redis桌面(GUI)管理客户端,兼容Windows、Mac、Linux,性能出众,轻松加载海量键值

Global site tag (gtag.js) - Google Analytics