属性对象针对每个属性一对象方式实现操作。
结构如下:
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; } ... }