archaius源碼分析之屬性對象
屬性對象針對每個屬性一對象方式實現操作。
結構如下:
Property
定義了屬性對象的基本方法,主要為獲取屬性值,獲取默認值,獲取屬性命令,管理回調函數。
public interface Property<T> { T getValue(); T getDefaultValue(); String getName(); long getChangedTimestamp(); void addCallback(Runnable callback); void removeAllCallbacks(); }
基本類型動態屬性
PropertyWrapper及其子類實現了基本類型屬性。
DynamicProperty實現了一個動態屬性,內部存儲屬性名,通過DynamicPropertySupport來獲取屬性,並實現PropertyListener來監聽屬性變更。PropertyWrapper內部封裝了DynamicProperty實現了具體類型的動態配置,子類指定了特定的類型。
DynamicPropertyFactory是創建動態屬性的工廠類。有兩種方式初始化,initWithConfigurationSource通過指定AbstractConfiguration來初始化,getInstance通過默認的AbstractConfiguration來初始化。AbstractConfiguration會被封裝成DynamicPropertySupport被DynamicProperty使用。
public static DynamicPropertyFactory initWithConfigurationSource(AbstractConfiguration config) { synchronized (ConfigurationManager.class) { ... if (config instanceof DynamicPropertySupport) { return initWithConfigurationSource((DynamicPropertySupport) config); }return initWithConfigurationSource(new ConfigurationBackedDynamicPropertySupportImpl(config)); } } public static DynamicPropertyFactory initWithConfigurationSource(DynamicPropertySupport dynamicPropertySupport) { synchronized (ConfigurationManager.class) { ... DynamicProperty.registerWithDynamicPropertySupport(support); initializedWithDefaultConfig = false; return instance; } }
public static DynamicPropertyFactory getInstance() { if (config == null) { synchronized (ConfigurationManager.class) { if (config == null) { AbstractConfiguration configFromManager = ConfigurationManager.getConfigInstance(); if (configFromManager != null) { initWithConfigurationSource(configFromManager); initializedWithDefaultConfig = !ConfigurationManager.isConfigurationInstalled(); logger.info("DynamicPropertyFactory is initialized with configuration sources: " + configFromManager); } } } } return instance; }
集合屬性
DynamicListProperty,DynamicSetProperty實現了集合屬性,底層通過DynamicStringProperty實現,屬性值通過分隔符分割。
protected void load() { if (delegate.get() == null) { values = defaultValues; } else { values = transform(split(delegate.get())); } }
鏈式屬性
動態屬性鏈(ChainLink),內部包含一個動態類屬性和指向下一個動態類屬性。如果當前動態類屬性無法獲得值,則會獲取下一個動態類屬性返回。每一個屬性的值是一個鏈式的結構,每個節點都會存儲一個屬性值,獲取屬性值時,會一個節點一個節點獲取,直到取到符合要求的值。ChainLink代表鏈式中的一個節點,內部有pReference代表最終的屬性值節點,next指向下一個節點。getReferencedProperty是該節點存儲的屬性值。checkAndFlip方法邏輯,當當前節點是最後一個節點時,當前節點就是最終屬性值節點;當當前節點不是最後一個節點時,如果當前節點是可用屬性值,則當前節點為屬性值節點,如果當前節點是不可用值,則設置下一個節點為最終的屬性值節點。get方法邏輯,如果當前節點為最終屬性值節點,獲取當前節點值,如果當前節點不是屬性節點,通過下一個節點獲取值。
public static abstract class ChainLink<T> implements Property<T> { ... private final AtomicReference<ChainLink<T>> pReference; private final ChainLink<T> next; public abstract boolean isValueAcceptable(); protected abstract Property<T> getReferencedProperty(); public ChainLink(T defaultValue) { next = null; pReference = new AtomicReference<ChainLink<T>>(this); ... } public ChainLink(ChainLink<T> nextProperty) { next = nextProperty; pReference = new AtomicReference<ChainLink<T>>(next); ... } protected void checkAndFlip() { if(next == null) { pReference.set(this); return; } if (this.isValueAcceptable()) { pReference.set(this); } else { pReference.set(next); } for (Runnable r : callbacks) { r.run(); } } public T get() { if (pReference.get() == this) { return this.getValue(); } else { return pReference.get().get(); } } @Override public T getValue() { return getReferencedProperty().getValue(); }
... }
子類BooleanProperty為例,DynamicBooleanPropertyThatSupportsNull是實際獲取屬性值的類,
public static class BooleanProperty extends ChainLink<Boolean> { private final DynamicBooleanPropertyThatSupportsNull sProp; ... public BooleanProperty(String name, BooleanProperty next) { super(next); // setup next pointer sProp = new DynamicBooleanPropertyThatSupportsNull(name, null); ... checkAndFlip(); } @Override public boolean isValueAcceptable() { return (sProp.getValue() != null); } @Override protected Property<Boolean> getReferencedProperty() { return sProp; } ... }
archaius源碼分析之屬性對象