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();
}
}
}
分享到:
相关推荐
本通用类设计的目标是高效地解析和操作ini配置文件,利用STL(Standard Template Library)容器来提升处理效率。 一、ini配置文件格式 ini文件通常由多个节(Section)组成,每个节包含一组键值对(Key-Value Pairs...
1. 加载配置文件:通过`Properties.load(InputStream)`方法加载文件,通常在类路径下查找文件。 2. 获取属性值:使用`Properties.getProperty(String key)`方法获取特定键对应的值。 3. 遍历所有属性:通过迭代`...
对于分类展示,可能需要定义一些通用的类,如列表项的样式,或者导航栏的样式。 5. `pages`目录:这是存放小程序所有页面的文件夹,每个分类层级可能对应一个或多个页面。页面结构通常包括`.json`(页面配置)、`....
了解Struts2配置文件的加载顺序对于优化应用性能和解决配置问题至关重要。 Struts2的配置主要分布在以下几个文件中: 1. **struts-default.xml**:这是Struts2的核心配置文件,位于`struts2-core.jar`库的`/org/...
在类的构造函数中,可以调用一个初始化方法,用宏定义的所有配置项来加载整个配置文件。 为了简化写入配置文件的过程,可以定义另一个宏`CONFIG_SAVE_PROPERTY`,它负责将所有已设置的配置项写回文件。这样,只需要...
ctFileINI.py 是一个功能丰富的Python通用类,它专为INI格式的配置文件读写而设计。该类提供了三个核心方法,分别用于读取配置文件、写入配置文件以及创建新的配置文件,从而满足开发者在配置管理方面的各种需求。 ...
// 加载配置文件, 查询 header 所对应的类的名字 String s = "org.bromon.reflect." + this.loadProtocal(header); // 加载类 Class<?> c = Class.forName(s); // 创建类的实例 Operator mo = (Operator) c....
"通用分页Jar 配置文件"通常是指一个可复用的Java库,它封装了分页逻辑,使得开发者可以在多个项目中方便地进行数据分页显示。这个库通常会包含配置文件、Java类和相关的资源文件,如TLD(Tag Library Descriptor)...
在C++编程中,处理配置文件通常是为了存储和读取应用程序的设置或用户偏好。ini文件是一种常见的配置文件格式,其结构简单,易于理解和操作。本文将深入探讨如何使用C++来读写ini配置文件,主要参考提供的"rwconfig....
// 加载配置文件 log4net.Config.XmlConfigurator.Configure(); } public static void Info(string message) { log.Info(message); } public static void Debug(string message) { log.Debug(message); ...
实际应用中,可以编写一个通用的辅助类`PropHelper`,提供一个静态方法来智能地查找并返回配置文件的输入流。这个方法不仅会尝试从指定类的包路径下寻找配置文件,还会检查类路径的其他位置,如JAR文件的根目录、...
5. **配置文件的使用流程**:在C++程序中,通常会在程序启动时读取配置文件,将配置信息加载到内存中,然后在需要的时候调用。这可以通过在主函数中调用一个配置读取函数来完成,该函数可以使用上述提到的库来解析...
- **配置文件位置**:在"common-config"模块中,我们可以创建一个名为`application.yml`或`application.properties`的配置文件,存储所有模块通用的配置项。 - **引入配置**:在其他模块如`service-module`、`data...
它们主要分为两类:全局配置文件和区域配置文件。全局配置文件如`CldConfig.ini`,涵盖了整个系统的通用设置,如屏幕分辨率、语言选择、声音设置等;而区域配置文件如`CityCode.ini`则包含特定地区的地图信息和设置...
- **外部加载**:除了类路径下的配置文件,还可以通过`--spring.config.location`命令行参数指定额外的配置文件位置。 - **环境变量**:使用`SPRING_APPLICATION_JSON`环境变量或`@PropertySource`注解也可以引入...
### Struts2配置文件介绍 #### 一、Struts2的核心配置文件 在Struts2框架中,有多个重要的配置文件用于控制应用的行为与结构,其中最核心的是`struts.xml`文件。此外还包括`web.xml`、`struts.properties`、`...
配置文件中会明确指定该驱动类的全限定名,以便程序在运行时加载合适的驱动。 2. **数据库URL**:这是一个特定于数据库的字符串,用于标识数据库的位置。例如,MySQL可能看起来像`jdbc:mysql://localhost:3306/...
1. **加载配置文件**:首先,`PropertiesUtil`需要有一个方法来加载`.properties`文件。这可以通过`java.util.Properties`类的`load()`方法实现,该方法接受一个`InputStream`对象作为参数。可以使用`ClassLoader`来...
4. **SysConfigUtil.java**:与`SystemConfig.java`类似,这个类可能是一个系统配置的通用工具类,提供了对XML配置文件的便利操作。它可能包含一些辅助方法,如读取特定配置项、验证配置值等,以简化开发者的代码。 ...
SPI机制则是一种服务提供者接口的机制,它允许第三方为某个接口实现提供实现,通过扩展名定的目录(通常是META-INF/services/目录)中的配置文件,服务提供方指定的实现类的全限定名,从而使得服务加载器可以动态地...