Spring PropertySources
- Author: HuiFer
- 源码阅读仓库: SourceHot-spring
MutablePropertySources
全路径:
org.springframework.core.env.MutablePropertySourcesMutablePropertySources类内部存储了List<PropertySource<?>>对象,主要是针对List<PropertySource<?>>进行的操作.换句话说就是对 list 操作的实现类注解如下
public class MutablePropertySources implements PropertySources {private final List<PropertySource<?>> propertySourceList = new CopyOnWriteArrayList<>();/*** Create a new {@link MutablePropertySources} object.** 构造方法*/public MutablePropertySources() {}/*** Create a new {@code MutablePropertySources} from the given propertySources* object, preserving the original order of contained {@code PropertySource} objects.* 构造方法, 传递一个集合, 将集合中的数据放入 {@code propertySourceList}.*/public MutablePropertySources(PropertySources propertySources) {this();// PropertySources 是一个迭代器接口的实现,通过循环取出信息放入到 propertySourceList 中for (PropertySource<?> propertySource : propertySources) {// 放入方法addLast(propertySource);}}/*** 获取迭代器对象*/@Overridepublic Iterator<PropertySource<?>> iterator() {return this.propertySourceList.iterator();}/*** 获取 Spliterator 对象*/@Overridepublic Spliterator<PropertySource<?>> spliterator() {return Spliterators.spliterator(this.propertySourceList, 0);}/*** 获取流*/@Overridepublic Stream<PropertySource<?>> stream() {return this.propertySourceList.stream();}/*** 判断是否存在 name* @param name the {@linkplain PropertySource#getName() name of the property source} to find*/@Overridepublic boolean contains(String name) {return this.propertySourceList.contains(PropertySource.named(name));}/*** 获取 PropertySource 信息* @param name the {@linkplain PropertySource#getName() name of the property source} to find* @return*/@Override@Nullablepublic PropertySource<?> get(String name) {// 获取 name 所在的索引位置int index = this.propertySourceList.indexOf(PropertySource.named(name));// get方法获取结果return (index != -1 ? this.propertySourceList.get(index) : null);}/*** Add the given property source object with highest precedence.** 头插数据*/public void addFirst(PropertySource<?> propertySource) {removeIfPresent(propertySource);this.propertySourceList.add(0, propertySource);}/*** Add the given property source object with lowest precedence.** 尾插数据*/public void addLast(PropertySource<?> propertySource) {removeIfPresent(propertySource);this.propertySourceList.add(propertySource);}/*** Add the given property source object with precedence immediately higher* than the named relative property source.** 在relativePropertySourceName的索引位置前添加数据*/public void addBefore(String relativePropertySourceName, PropertySource<?> propertySource) {assertLegalRelativeAddition(relativePropertySourceName, propertySource);removeIfPresent(propertySource);int index = assertPresentAndGetIndex(relativePropertySourceName);addAtIndex(index, propertySource);}/*** Add the given property source object with precedence immediately lower* than the named relative property source.* 在relativePropertySourceName的索引位置后添加数据*/public void addAfter(String relativePropertySourceName, PropertySource<?> propertySource) {assertLegalRelativeAddition(relativePropertySourceName, propertySource);// 删除存在的数据removeIfPresent(propertySource);// 获取所有int index = assertPresentAndGetIndex(relativePropertySourceName);// 在索引+1出添加数据addAtIndex(index + 1, propertySource);}/*** Return the precedence of the given property source, {@code -1} if not found.* 获取索引位置*/public int precedenceOf(PropertySource<?> propertySource) {return this.propertySourceList.indexOf(propertySource);}/*** Remove and return the property source with the given name, {@code null} if not found.* 删除索引位置* @param name the name of the property source to find and remove*/@Nullablepublic PropertySource<?> remove(String name) {// 获取索引int index = this.propertySourceList.indexOf(PropertySource.named(name));// 删除索引上的数据return (index != -1 ? this.propertySourceList.remove(index) : null);}/*** Replace the property source with the given name with the given property source object.* 替换 name 的信息* @param name the name of the property source to find and replace* @param propertySource the replacement property source* @throws IllegalArgumentException if no property source with the given name is present* @see #contains*/public void replace(String name, PropertySource<?> propertySource) {// 获取索引位置int index = assertPresentAndGetIndex(name);// 设置具体所应位置的值this.propertySourceList.set(index, propertySource);}/*** Return the number of {@link PropertySource} objects contained.* 数量*/public int size() {return this.propertySourceList.size();}@Overridepublic String toString() {return this.propertySourceList.toString();}/*** Ensure that the given property source is not being added relative to itself.* 确保两个 PropertySource 的 name不相同*/protected void assertLegalRelativeAddition(String relativePropertySourceName, PropertySource<?> propertySource) {// 获取 PropertySource 的名字String newPropertySourceName = propertySource.getName();// 历史名字和新的名字是否相同if (relativePropertySourceName.equals(newPropertySourceName)) {throw new IllegalArgumentException("PropertySource named '" + newPropertySourceName + "' cannot be added relative to itself");}}/*** Remove the given property source if it is present.* 删除已存在的数据*/protected void removeIfPresent(PropertySource<?> propertySource) {this.propertySourceList.remove(propertySource);}/*** Add the given property source at a particular index in the list.* 指定索引位置插入数据*/private void addAtIndex(int index, PropertySource<?> propertySource) {removeIfPresent(propertySource);this.propertySourceList.add(index, propertySource);}/*** Assert that the named property source is present and return its index.* 获取 name 所在的索引位置* @param name {@linkplain PropertySource#getName() name of the property source} to find* @throws IllegalArgumentException if the named property source is not present*/private int assertPresentAndGetIndex(String name) {int index = this.propertySourceList.indexOf(PropertySource.named(name));if (index == -1) {throw new IllegalArgumentException("PropertySource named '" + name + "' does not exist");}return index;}}
PropertySources
类路径:
org.springframework.core.env.PropertySources详细说明如下
public interface PropertySources extends Iterable<PropertySource<?>> {/*** Return a sequential {@link Stream} containing the property sources.* 获取流* @since 5.1*/default Stream<PropertySource<?>> stream() {return StreamSupport.stream(spliterator(), false);}/*** Return whether a property source with the given name is contained.* 判断是否存在 name* @param name the {@linkplain PropertySource#getName() name of the property source} to find*/boolean contains(String name);/*** Return the property source with the given name, {@code null} if not found.* 获取 PropertySource* @param name the {@linkplain PropertySource#getName() name of the property source} to find*/@NullablePropertySource<?> get(String name);}
PropertySource
类路径:
org.springframework.core.env.PropertySource存有两个子类
- StubPropertySource
- ComparisonPropertySource 3. 调用
getSource、containsProperty、getProperty都会直接异常
public abstract class PropertySource<T> {protected final Log logger = LogFactory.getLog(getClass());/*** 属性名称*/protected final String name;/*** 值*/protected final T source;/*** Create a new {@code PropertySource} with the given name and source object.*/public PropertySource(String name, T source) {Assert.hasText(name, "Property source name must contain at least one character");Assert.notNull(source, "Property source must not be null");this.name = name;this.source = source;}/*** Create a new {@code PropertySource} with the given name and with a new* {@code Object} instance as the underlying source.* <p>Often useful in testing scenarios when creating anonymous implementations* that never query an actual source but rather return hard-coded values.*/@SuppressWarnings("unchecked")public PropertySource(String name) {this(name, (T) new Object());}/*** Return a {@code PropertySource} implementation intended for collection comparison purposes only.* <p>Primarily for internal use, but given a collection of {@code PropertySource} objects, may be* used as follows:* <pre class="code">* {@code List<PropertySource<?>> sources = new ArrayList<PropertySource<?>>();* sources.add(new MapPropertySource("sourceA", mapA));* sources.add(new MapPropertySource("sourceB", mapB));* assert sources.contains(PropertySource.named("sourceA"));* assert sources.contains(PropertySource.named("sourceB"));* assert !sources.contains(PropertySource.named("sourceC"));* }</pre>* The returned {@code PropertySource} will throw {@code UnsupportedOperationException}* if any methods other than {@code equals(Object)}, {@code hashCode()}, and {@code toString()}* are called.* @param name the name of the comparison {@code PropertySource} to be created and returned.*/public static PropertySource<?> named(String name) {return new ComparisonPropertySource(name);}/*** Return the name of this {@code PropertySource}.*/public String getName() {return this.name;}/*** Return the underlying source object for this {@code PropertySource}.*/public T getSource() {return this.source;}/*** Return whether this {@code PropertySource} contains the given name.* <p>This implementation simply checks for a {@code null} return value* from {@link #getProperty(String)}. Subclasses may wish to implement* a more efficient algorithm if possible.* @param name the property name to find*/public boolean containsProperty(String name) {// getProperty 抽象方法子类实现return (getProperty(name) != null);}/*** Return the value associated with the given name,* or {@code null} if not found.* // getProperty 抽象方法子类实现* @param name the property to find* @see PropertyResolver#getRequiredProperty(String)*/@Nullablepublic abstract Object getProperty(String name);/*** This {@code PropertySource} object is equal to the given object if:* <ul>* <li>they are the same instance* <li>the {@code name} properties for both objects are equal* </ul>* <p>No properties other than {@code name} are evaluated.*/@Overridepublic boolean equals(@Nullable Object other) {return (this == other || (other instanceof PropertySource &&ObjectUtils.nullSafeEquals(this.name, ((PropertySource<?>) other).name)));}/*** Return a hash code derived from the {@code name} property* of this {@code PropertySource} object.*/@Overridepublic int hashCode() {return ObjectUtils.nullSafeHashCode(this.name);}/*** Produce concise output (type and name) if the current log level does not include* debug. If debug is enabled, produce verbose output including the hash code of the* PropertySource instance and every name/value property pair.* <p>This variable verbosity is useful as a property source such as system properties* or environment variables may contain an arbitrary number of property pairs,* potentially leading to difficult to read exception and log messages.* @see Log#isDebugEnabled()*/@Overridepublic String toString() {if (logger.isDebugEnabled()) {return getClass().getSimpleName() + "@" + System.identityHashCode(this) +" {name='" + this.name + "', properties=" + this.source + "}";}else {return getClass().getSimpleName() + " {name='" + this.name + "'}";}}/*** {@code PropertySource} to be used as a placeholder in cases where an actual* property source cannot be eagerly initialized at application context* creation time. For example, a {@code ServletContext}-based property source* must wait until the {@code ServletContext} object is available to its enclosing* {@code ApplicationContext}. In such cases, a stub should be used to hold the* intended default position/order of the property source, then be replaced* during context refresh.* @see org.springframework.context.support.AbstractApplicationContext#initPropertySources()* @see org.springframework.web.context.support.StandardServletEnvironment* @see org.springframework.web.context.support.ServletContextPropertySource*/public static class StubPropertySource extends PropertySource<Object> {public StubPropertySource(String name) {super(name, new Object());}/*** Always returns {@code null}.*/@Override@Nullablepublic String getProperty(String name) {return null;}}/*** A {@code PropertySource} implementation intended for collection comparison* purposes.** @see PropertySource#named(String)*/static class ComparisonPropertySource extends StubPropertySource {// 异常信息private static final String USAGE_ERROR ="ComparisonPropertySource instances are for use with collection comparison only";public ComparisonPropertySource(String name) {super(name);}@Overridepublic Object getSource() {// 抛异常throw new UnsupportedOperationException(USAGE_ERROR);}@Overridepublic boolean containsProperty(String name) {// 抛异常throw new UnsupportedOperationException(USAGE_ERROR);}@Override@Nullablepublic String getProperty(String name) {// 抛异常throw new UnsupportedOperationException(USAGE_ERROR);}}}
类图

