Spring PropertySources

MutablePropertySources

  • 全路径: org.springframework.core.env.MutablePropertySources

  • MutablePropertySources类内部存储了List<PropertySource<?>>对象,主要是针对List<PropertySource<?>> 进行的操作.换句话说就是对 list 操作的实现

  • 类注解如下

  1. public class MutablePropertySources implements PropertySources {
  2. private final List<PropertySource<?>> propertySourceList = new CopyOnWriteArrayList<>();
  3. /**
  4. * Create a new {@link MutablePropertySources} object.
  5. *
  6. * 构造方法
  7. */
  8. public MutablePropertySources() {
  9. }
  10. /**
  11. * Create a new {@code MutablePropertySources} from the given propertySources
  12. * object, preserving the original order of contained {@code PropertySource} objects.
  13. * 构造方法, 传递一个集合, 将集合中的数据放入 {@code propertySourceList}.
  14. */
  15. public MutablePropertySources(PropertySources propertySources) {
  16. this();
  17. // PropertySources 是一个迭代器接口的实现,通过循环取出信息放入到 propertySourceList 中
  18. for (PropertySource<?> propertySource : propertySources) {
  19. // 放入方法
  20. addLast(propertySource);
  21. }
  22. }
  23. /**
  24. * 获取迭代器对象
  25. */
  26. @Override
  27. public Iterator<PropertySource<?>> iterator() {
  28. return this.propertySourceList.iterator();
  29. }
  30. /**
  31. * 获取 Spliterator 对象
  32. */
  33. @Override
  34. public Spliterator<PropertySource<?>> spliterator() {
  35. return Spliterators.spliterator(this.propertySourceList, 0);
  36. }
  37. /**
  38. * 获取流
  39. */
  40. @Override
  41. public Stream<PropertySource<?>> stream() {
  42. return this.propertySourceList.stream();
  43. }
  44. /**
  45. * 判断是否存在 name
  46. * @param name the {@linkplain PropertySource#getName() name of the property source} to find
  47. */
  48. @Override
  49. public boolean contains(String name) {
  50. return this.propertySourceList.contains(PropertySource.named(name));
  51. }
  52. /**
  53. * 获取 PropertySource 信息
  54. * @param name the {@linkplain PropertySource#getName() name of the property source} to find
  55. * @return
  56. */
  57. @Override
  58. @Nullable
  59. public PropertySource<?> get(String name) {
  60. // 获取 name 所在的索引位置
  61. int index = this.propertySourceList.indexOf(PropertySource.named(name));
  62. // get方法获取结果
  63. return (index != -1 ? this.propertySourceList.get(index) : null);
  64. }
  65. /**
  66. * Add the given property source object with highest precedence.
  67. *
  68. * 头插数据
  69. */
  70. public void addFirst(PropertySource<?> propertySource) {
  71. removeIfPresent(propertySource);
  72. this.propertySourceList.add(0, propertySource);
  73. }
  74. /**
  75. * Add the given property source object with lowest precedence.
  76. *
  77. * 尾插数据
  78. */
  79. public void addLast(PropertySource<?> propertySource) {
  80. removeIfPresent(propertySource);
  81. this.propertySourceList.add(propertySource);
  82. }
  83. /**
  84. * Add the given property source object with precedence immediately higher
  85. * than the named relative property source.
  86. *
  87. * 在relativePropertySourceName的索引位置前添加数据
  88. */
  89. public void addBefore(String relativePropertySourceName, PropertySource<?> propertySource) {
  90. assertLegalRelativeAddition(relativePropertySourceName, propertySource);
  91. removeIfPresent(propertySource);
  92. int index = assertPresentAndGetIndex(relativePropertySourceName);
  93. addAtIndex(index, propertySource);
  94. }
  95. /**
  96. * Add the given property source object with precedence immediately lower
  97. * than the named relative property source.
  98. * 在relativePropertySourceName的索引位置后添加数据
  99. */
  100. public void addAfter(String relativePropertySourceName, PropertySource<?> propertySource) {
  101. assertLegalRelativeAddition(relativePropertySourceName, propertySource);
  102. // 删除存在的数据
  103. removeIfPresent(propertySource);
  104. // 获取所有
  105. int index = assertPresentAndGetIndex(relativePropertySourceName);
  106. // 在索引+1出添加数据
  107. addAtIndex(index + 1, propertySource);
  108. }
  109. /**
  110. * Return the precedence of the given property source, {@code -1} if not found.
  111. * 获取索引位置
  112. */
  113. public int precedenceOf(PropertySource<?> propertySource) {
  114. return this.propertySourceList.indexOf(propertySource);
  115. }
  116. /**
  117. * Remove and return the property source with the given name, {@code null} if not found.
  118. * 删除索引位置
  119. * @param name the name of the property source to find and remove
  120. */
  121. @Nullable
  122. public PropertySource<?> remove(String name) {
  123. // 获取索引
  124. int index = this.propertySourceList.indexOf(PropertySource.named(name));
  125. // 删除索引上的数据
  126. return (index != -1 ? this.propertySourceList.remove(index) : null);
  127. }
  128. /**
  129. * Replace the property source with the given name with the given property source object.
  130. * 替换 name 的信息
  131. * @param name the name of the property source to find and replace
  132. * @param propertySource the replacement property source
  133. * @throws IllegalArgumentException if no property source with the given name is present
  134. * @see #contains
  135. */
  136. public void replace(String name, PropertySource<?> propertySource) {
  137. // 获取索引位置
  138. int index = assertPresentAndGetIndex(name);
  139. // 设置具体所应位置的值
  140. this.propertySourceList.set(index, propertySource);
  141. }
  142. /**
  143. * Return the number of {@link PropertySource} objects contained.
  144. * 数量
  145. */
  146. public int size() {
  147. return this.propertySourceList.size();
  148. }
  149. @Override
  150. public String toString() {
  151. return this.propertySourceList.toString();
  152. }
  153. /**
  154. * Ensure that the given property source is not being added relative to itself.
  155. * 确保两个 PropertySource 的 name不相同
  156. */
  157. protected void assertLegalRelativeAddition(String relativePropertySourceName, PropertySource<?> propertySource) {
  158. // 获取 PropertySource 的名字
  159. String newPropertySourceName = propertySource.getName();
  160. // 历史名字和新的名字是否相同
  161. if (relativePropertySourceName.equals(newPropertySourceName)) {
  162. throw new IllegalArgumentException(
  163. "PropertySource named '" + newPropertySourceName + "' cannot be added relative to itself");
  164. }
  165. }
  166. /**
  167. * Remove the given property source if it is present.
  168. * 删除已存在的数据
  169. */
  170. protected void removeIfPresent(PropertySource<?> propertySource) {
  171. this.propertySourceList.remove(propertySource);
  172. }
  173. /**
  174. * Add the given property source at a particular index in the list.
  175. * 指定索引位置插入数据
  176. */
  177. private void addAtIndex(int index, PropertySource<?> propertySource) {
  178. removeIfPresent(propertySource);
  179. this.propertySourceList.add(index, propertySource);
  180. }
  181. /**
  182. * Assert that the named property source is present and return its index.
  183. * 获取 name 所在的索引位置
  184. * @param name {@linkplain PropertySource#getName() name of the property source} to find
  185. * @throws IllegalArgumentException if the named property source is not present
  186. */
  187. private int assertPresentAndGetIndex(String name) {
  188. int index = this.propertySourceList.indexOf(PropertySource.named(name));
  189. if (index == -1) {
  190. throw new IllegalArgumentException("PropertySource named '" + name + "' does not exist");
  191. }
  192. return index;
  193. }
  194. }

PropertySources

  • 类路径: org.springframework.core.env.PropertySources

  • 详细说明如下

  1. public interface PropertySources extends Iterable<PropertySource<?>> {
  2. /**
  3. * Return a sequential {@link Stream} containing the property sources.
  4. * 获取流
  5. * @since 5.1
  6. */
  7. default Stream<PropertySource<?>> stream() {
  8. return StreamSupport.stream(spliterator(), false);
  9. }
  10. /**
  11. * Return whether a property source with the given name is contained.
  12. * 判断是否存在 name
  13. * @param name the {@linkplain PropertySource#getName() name of the property source} to find
  14. */
  15. boolean contains(String name);
  16. /**
  17. * Return the property source with the given name, {@code null} if not found.
  18. * 获取 PropertySource
  19. * @param name the {@linkplain PropertySource#getName() name of the property source} to find
  20. */
  21. @Nullable
  22. PropertySource<?> get(String name);
  23. }

PropertySource

  • 类路径: org.springframework.core.env.PropertySource

  • 存有两个子类

    1. StubPropertySource
    2. ComparisonPropertySource 3. 调用getSourcecontainsPropertygetProperty 都会直接异常
  1. public abstract class PropertySource<T> {
  2. protected final Log logger = LogFactory.getLog(getClass());
  3. /**
  4. * 属性名称
  5. */
  6. protected final String name;
  7. /**
  8. * 值
  9. */
  10. protected final T source;
  11. /**
  12. * Create a new {@code PropertySource} with the given name and source object.
  13. */
  14. public PropertySource(String name, T source) {
  15. Assert.hasText(name, "Property source name must contain at least one character");
  16. Assert.notNull(source, "Property source must not be null");
  17. this.name = name;
  18. this.source = source;
  19. }
  20. /**
  21. * Create a new {@code PropertySource} with the given name and with a new
  22. * {@code Object} instance as the underlying source.
  23. * <p>Often useful in testing scenarios when creating anonymous implementations
  24. * that never query an actual source but rather return hard-coded values.
  25. */
  26. @SuppressWarnings("unchecked")
  27. public PropertySource(String name) {
  28. this(name, (T) new Object());
  29. }
  30. /**
  31. * Return a {@code PropertySource} implementation intended for collection comparison purposes only.
  32. * <p>Primarily for internal use, but given a collection of {@code PropertySource} objects, may be
  33. * used as follows:
  34. * <pre class="code">
  35. * {@code List<PropertySource<?>> sources = new ArrayList<PropertySource<?>>();
  36. * sources.add(new MapPropertySource("sourceA", mapA));
  37. * sources.add(new MapPropertySource("sourceB", mapB));
  38. * assert sources.contains(PropertySource.named("sourceA"));
  39. * assert sources.contains(PropertySource.named("sourceB"));
  40. * assert !sources.contains(PropertySource.named("sourceC"));
  41. * }</pre>
  42. * The returned {@code PropertySource} will throw {@code UnsupportedOperationException}
  43. * if any methods other than {@code equals(Object)}, {@code hashCode()}, and {@code toString()}
  44. * are called.
  45. * @param name the name of the comparison {@code PropertySource} to be created and returned.
  46. */
  47. public static PropertySource<?> named(String name) {
  48. return new ComparisonPropertySource(name);
  49. }
  50. /**
  51. * Return the name of this {@code PropertySource}.
  52. */
  53. public String getName() {
  54. return this.name;
  55. }
  56. /**
  57. * Return the underlying source object for this {@code PropertySource}.
  58. */
  59. public T getSource() {
  60. return this.source;
  61. }
  62. /**
  63. * Return whether this {@code PropertySource} contains the given name.
  64. * <p>This implementation simply checks for a {@code null} return value
  65. * from {@link #getProperty(String)}. Subclasses may wish to implement
  66. * a more efficient algorithm if possible.
  67. * @param name the property name to find
  68. */
  69. public boolean containsProperty(String name) {
  70. // getProperty 抽象方法子类实现
  71. return (getProperty(name) != null);
  72. }
  73. /**
  74. * Return the value associated with the given name,
  75. * or {@code null} if not found.
  76. * // getProperty 抽象方法子类实现
  77. * @param name the property to find
  78. * @see PropertyResolver#getRequiredProperty(String)
  79. */
  80. @Nullable
  81. public abstract Object getProperty(String name);
  82. /**
  83. * This {@code PropertySource} object is equal to the given object if:
  84. * <ul>
  85. * <li>they are the same instance
  86. * <li>the {@code name} properties for both objects are equal
  87. * </ul>
  88. * <p>No properties other than {@code name} are evaluated.
  89. */
  90. @Override
  91. public boolean equals(@Nullable Object other) {
  92. return (this == other || (other instanceof PropertySource &&
  93. ObjectUtils.nullSafeEquals(this.name, ((PropertySource<?>) other).name)));
  94. }
  95. /**
  96. * Return a hash code derived from the {@code name} property
  97. * of this {@code PropertySource} object.
  98. */
  99. @Override
  100. public int hashCode() {
  101. return ObjectUtils.nullSafeHashCode(this.name);
  102. }
  103. /**
  104. * Produce concise output (type and name) if the current log level does not include
  105. * debug. If debug is enabled, produce verbose output including the hash code of the
  106. * PropertySource instance and every name/value property pair.
  107. * <p>This variable verbosity is useful as a property source such as system properties
  108. * or environment variables may contain an arbitrary number of property pairs,
  109. * potentially leading to difficult to read exception and log messages.
  110. * @see Log#isDebugEnabled()
  111. */
  112. @Override
  113. public String toString() {
  114. if (logger.isDebugEnabled()) {
  115. return getClass().getSimpleName() + "@" + System.identityHashCode(this) +
  116. " {name='" + this.name + "', properties=" + this.source + "}";
  117. }
  118. else {
  119. return getClass().getSimpleName() + " {name='" + this.name + "'}";
  120. }
  121. }
  122. /**
  123. * {@code PropertySource} to be used as a placeholder in cases where an actual
  124. * property source cannot be eagerly initialized at application context
  125. * creation time. For example, a {@code ServletContext}-based property source
  126. * must wait until the {@code ServletContext} object is available to its enclosing
  127. * {@code ApplicationContext}. In such cases, a stub should be used to hold the
  128. * intended default position/order of the property source, then be replaced
  129. * during context refresh.
  130. * @see org.springframework.context.support.AbstractApplicationContext#initPropertySources()
  131. * @see org.springframework.web.context.support.StandardServletEnvironment
  132. * @see org.springframework.web.context.support.ServletContextPropertySource
  133. */
  134. public static class StubPropertySource extends PropertySource<Object> {
  135. public StubPropertySource(String name) {
  136. super(name, new Object());
  137. }
  138. /**
  139. * Always returns {@code null}.
  140. */
  141. @Override
  142. @Nullable
  143. public String getProperty(String name) {
  144. return null;
  145. }
  146. }
  147. /**
  148. * A {@code PropertySource} implementation intended for collection comparison
  149. * purposes.
  150. *
  151. * @see PropertySource#named(String)
  152. */
  153. static class ComparisonPropertySource extends StubPropertySource {
  154. // 异常信息
  155. private static final String USAGE_ERROR =
  156. "ComparisonPropertySource instances are for use with collection comparison only";
  157. public ComparisonPropertySource(String name) {
  158. super(name);
  159. }
  160. @Override
  161. public Object getSource() {
  162. // 抛异常
  163. throw new UnsupportedOperationException(USAGE_ERROR);
  164. }
  165. @Override
  166. public boolean containsProperty(String name) {
  167. // 抛异常
  168. throw new UnsupportedOperationException(USAGE_ERROR);
  169. }
  170. @Override
  171. @Nullable
  172. public String getProperty(String name) {
  173. // 抛异常
  174. throw new UnsupportedOperationException(USAGE_ERROR);
  175. }
  176. }
  177. }

类图

PropertySource.png