先上一个例子代码
public static void main( String[] args ) throws IOException {
DynamicStringProperty stringProperty = DynamicPropertyFactory.getInstance().getStringProperty( "hello", "" );
System.out.println( stringProperty.get() );
ConfigurationManager.getConfigInstance().setProperty( "name", "Jay" );
ConfigurationManager.getConfigInstance().setProperty( "name", "Join" );
System.out.println( ConfigurationManager.getConfigInstance().getString( "name" ) );
ConfigurationManager.loadCascadedPropertiesFromResources( "application" );
// eureka-client
DynamicPropertyFactory propertyFactory = Archaius1Utils.initConfig( CommonConstants.CONFIG_FILE_NAME );
System.out.println( propertyFactory.getStringProperty( "a", "" ).get() );
}
src/main/resources 需要有 application.properties, config.properties, eureka-client.properties 这几个properties 文件。如图:
ConfigurationManager.getConfigInstance(); 默认是加载 src/main/resources 下的 config.properties 文件。
下面 看看源代码是怎么做的
public static AbstractConfiguration getConfigInstance() {
if ( instance == null ) {
synchronized ( ConfigurationManager.class ) {
if ( instance == null ) {
// archaius.dynamicProperty.disableDefaultConfig
instance = getConfigInstance( Boolean.getBoolean( DynamicPropertyFactory.DISABLE_DEFAULT_CONFIG ) );
}
}
}
return instance;
}
单例模式 获取 AbstractConfiguration
// false
private static AbstractConfiguration getConfigInstance( boolean defaultConfigDisabled ) {
if ( instance == null && !defaultConfigDisabled ) {
instance = createDefaultConfigInstance();
registerConfigBean();
}
return instance;
}
直接 看 createDefaultConfigInstance 方法
private static AbstractConfiguration createDefaultConfigInstance() {
// 组合配置
ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();
try {
DynamicURLConfiguration defaultURLConfig = new DynamicURLConfiguration();
// archaius.dynamicPropertyFactory.URL_CONFIG
config.addConfiguration( defaultURLConfig, URL_CONFIG_NAME );
} catch ( Throwable e ) {
logger.warn( "Failed to create default dynamic configuration", e );
}
// archaius.dynamicProperty.disableSystemConfig
if ( !Boolean.getBoolean( DISABLE_DEFAULT_SYS_CONFIG ) ) {
SystemConfiguration sysConfig = new SystemConfiguration();
config.addConfiguration( sysConfig, SYS_CONFIG_NAME );
}
// archaius.dynamicProperty.disableEnvironmentConfig
if ( !Boolean.getBoolean( DISABLE_DEFAULT_ENV_CONFIG ) ) {
EnvironmentConfiguration envConfig = new EnvironmentConfiguration();
config.addConfiguration( envConfig, ENV_CONFIG_NAME );
}
ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration();
// APPLICATION_PROPERTIES
config.addConfiguration( appOverrideConfig, APPLICATION_PROPERTIES );
config.setContainerConfigurationIndex( config.getIndexOfConfiguration( appOverrideConfig ) );
return config;
}
ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();
这个类是一个配置的集合,可以加载多个配置文件,每个配置文件都加在到自己单独的AbstractConfiguration 中。
private Map<String, AbstractConfiguration> namedConfigurations = new ConcurrentHashMap<String, AbstractConfiguration>();
private List<AbstractConfiguration> configList = new CopyOnWriteArrayList<AbstractConfiguration>();
configList 就是配置的集合, 如果要查找 其中的一个属性配置,就要循环 configList 中的每一个 AbstractConfiguration 一直到找到为止。
ConcurrentCompositeConfiguration 这个类默认添加一个 ConcurrentMapConfiguration ,使用的观察者模式, 代码如下
public final void clear() {
fireEvent( EVENT_CLEAR, null, null, true );
configList.clear();
namedConfigurations.clear();
// recreate the in memory configuration
containerConfiguration = new ConcurrentMapConfiguration();
containerConfiguration.setThrowExceptionOnMissing( isThrowExceptionOnMissing() );
containerConfiguration.setListDelimiter( getListDelimiter() );
containerConfiguration.setDelimiterParsingDisabled( isDelimiterParsingDisabled() );
containerConfiguration.addConfigurationListener( eventPropagater );
configList.add( containerConfiguration );
overrideProperties = new ConcurrentMapConfiguration();
overrideProperties.setThrowExceptionOnMissing( isThrowExceptionOnMissing() );
overrideProperties.setListDelimiter( getListDelimiter() );
overrideProperties.setDelimiterParsingDisabled( isDelimiterParsingDisabled() );
overrideProperties.addConfigurationListener( eventPropagater );
fireEvent( EVENT_CLEAR, null, null, false );
containerConfigurationChanged = false;
invalidate();
}
接下来看着2行代码
DynamicURLConfiguration defaultURLConfig = new DynamicURLConfiguration();
// archaius.dynamicPropertyFactory.URL_CONFIG
config.addConfiguration( defaultURLConfig, URL_CONFIG_NAME );
DynamicURLConfiguration 中的默认加载 config.properties 文件, 并且加入到 ConcurrentCompositeConfiguration 类中。
public DynamicURLConfiguration() {
URLConfigurationSource source = new URLConfigurationSource();
if ( source.getConfigUrls() != null && source.getConfigUrls().size() > 0 ) {
startPolling( source, new FixedDelayPollingScheduler() );
}
}
public URLConfigurationSource() {
List<URL> urlList = new ArrayList<URL>();
URL configFromClasspath = getConfigFileFromClasspath();
if ( configFromClasspath != null ) {
urlList.add( configFromClasspath );
}
String[] fileNames = getDefaultFileSources();
if ( fileNames.length != 0 ) {
urlList.addAll( Arrays.asList( createUrls( fileNames ) ) );
}
if ( urlList.size() == 0 ) {
configUrls = new URL[ 0 ];
} else {
configUrls = urlList.toArray( new URL[ urlList.size() ] );
}
}
URL configFromClasspath = getConfigFileFromClasspath(); 看着一行
private URL getConfigFileFromClasspath() {
URL url = null;
// attempt to load from the context classpath
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if ( loader != null ) {
// config.properties
url = loader.getResource( DEFAULT_CONFIG_FILE_FROM_CLASSPATH );
}
if ( url == null ) {
// attempt to load from the system classpath
url = ClassLoader.getSystemResource( DEFAULT_CONFIG_FILE_FROM_CLASSPATH );
}
if ( url == null ) {
// attempt to load from the system classpath
url = URLConfigurationSource.class.getResource( DEFAULT_CONFIG_FILE_FROM_CLASSPATH );
}
return url;
}
public static final String DEFAULT_CONFIG_FILE_FROM_CLASSPATH = System.getProperty( "archaius.configurationSource.defaultFileName" ) == null ? DEFAULT_CONFIG_FILE_NAME : System.getProperty( "archaius.configurationSource.defaultFileName" );
也就是 config.properties 这个文件
也可以 -Darchaius.configurationSource.additionalUrls 加载指定的文件。 代码如下
private static final String[] getDefaultFileSources() {
// archaius.configurationSource.additionalUrls
String name = System.getProperty( CONFIG_URL );
String[] fileNames;
if ( name != null ) {
fileNames = name.split( "," );
} else {
fileNames = new String[ 0 ];
}
return fileNames;
}
DynamicURLConfiguration 还支持动态修改, 定时刷新
public DynamicURLConfiguration() {
URLConfigurationSource source = new URLConfigurationSource();
if ( source.getConfigUrls() != null && source.getConfigUrls().size() > 0 ) {
startPolling( source, new FixedDelayPollingScheduler() );
}
}
public FixedDelayPollingScheduler() {
// archaius.fixedDelayPollingScheduler.initialDelayMills
String initialDelayProperty = System.getProperty( INITIAL_DELAY_PROPERTY );
if ( initialDelayProperty != null && initialDelayProperty.length() > 0 ) {
initialDelayMillis = Integer.parseInt( initialDelayProperty );
}
// archaius.fixedDelayPollingScheduler.delayMills
String delayProperty = System.getProperty( DELAY_PROPERTY );
if ( delayProperty != null && delayProperty.length() > 0 ) {
delayMillis = Integer.parseInt( delayProperty );
}
}
可以通过 -Darchaius.fixedDelayPollingScheduler.initialDelayMills 设置初始化延时,
-Darchaius.fixedDelayPollingScheduler.delayMills设置多久重新加载一次
ConcurrentCompositeConfiguration 也可以禁止加载系统配置和环境配置
-Darchaius.dynamicProperty.disableSystemConfig 不加载系统配置
-Darchaius.dynamicProperty.disableEnvironmentConfig 不加载环境配置
-Darchaius.dynamicPropertyFactory.registerConfigWithJMX 设置启用JMX