Spring PropertyPlaceholderHelper

  • 类全路径: org.springframework.util.PropertyPlaceholderHelper

parseStringValue

  • org.springframework.util.PropertyPlaceholderHelper#parseStringValue 这个方法是主要方法
  1. protected String parseStringValue(
  2. String value, PlaceholderResolver placeholderResolver, @Nullable Set<String> visitedPlaceholders) {
  3. // 占位符所在位置
  4. int startIndex = value.indexOf(this.placeholderPrefix);
  5. if (startIndex == -1) {
  6. return value;
  7. }
  8. // 返回值
  9. StringBuilder result = new StringBuilder(value);
  10. while (startIndex != -1) {
  11. // 寻找结尾占位符
  12. int endIndex = findPlaceholderEndIndex(result, startIndex);
  13. if (endIndex != -1) {
  14. // 返回值切分留下中间内容
  15. String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
  16. String originalPlaceholder = placeholder;
  17. if (visitedPlaceholders == null) {
  18. visitedPlaceholders = new HashSet<>(4);
  19. }
  20. if (!visitedPlaceholders.add(originalPlaceholder)) {
  21. throw new IllegalArgumentException(
  22. "Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
  23. }
  24. // Recursive invocation, parsing placeholders contained in the placeholder key.
  25. // 递归获取占位符内容
  26. placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
  27. // Now obtain the value for the fully resolved key...
  28. // 解析占位符内容获得真正的属性值
  29. String propVal = placeholderResolver.resolvePlaceholder(placeholder);
  30. if (propVal == null && this.valueSeparator != null) {
  31. int separatorIndex = placeholder.indexOf(this.valueSeparator);
  32. if (separatorIndex != -1) {
  33. String actualPlaceholder = placeholder.substring(0, separatorIndex);
  34. String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
  35. propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
  36. if (propVal == null) {
  37. propVal = defaultValue;
  38. }
  39. }
  40. }
  41. if (propVal != null) {
  42. // Recursive invocation, parsing placeholders contained in the
  43. // previously resolved placeholder value.
  44. propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
  45. result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
  46. if (logger.isTraceEnabled()) {
  47. logger.trace("Resolved placeholder '" + placeholder + "'");
  48. }
  49. startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
  50. }
  51. else if (this.ignoreUnresolvablePlaceholders) {
  52. // Proceed with unprocessed value.
  53. startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
  54. }
  55. else {
  56. throw new IllegalArgumentException("Could not resolve placeholder '" +
  57. placeholder + "'" + " in value \"" + value + "\"");
  58. }
  59. visitedPlaceholders.remove(originalPlaceholder);
  60. }
  61. else {
  62. startIndex = -1;
  63. }
  64. }
  65. return result.toString();
  66. }

在这里还需要关注一个接口

  • 占位符解析.
  1. @FunctionalInterface
  2. public interface PlaceholderResolver {
  3. /**
  4. * Resolve the supplied placeholder name to the replacement value.
  5. * @param placeholderName the name of the placeholder to resolve
  6. * @return the replacement value, or {@code null} if no replacement is to be made
  7. */
  8. @Nullable
  9. String resolvePlaceholder(String placeholderName);
  10. }

占位符解析请查看: PlaceholderResolver

findPlaceholderEndIndex

  • 寻找结尾占位符索引
  1. /**
  2. * 寻找结尾占位符索引
  3. */
  4. private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
  5. int index = startIndex + this.placeholderPrefix.length();
  6. int withinNestedPlaceholder = 0;
  7. while (index < buf.length()) {
  8. if (StringUtils.substringMatch(buf, index, this.placeholderSuffix)) {
  9. if (withinNestedPlaceholder > 0) {
  10. withinNestedPlaceholder--;
  11. index = index + this.placeholderSuffix.length();
  12. }
  13. else {
  14. return index;
  15. }
  16. }
  17. else if (StringUtils.substringMatch(buf, index, this.simplePrefix)) {
  18. withinNestedPlaceholder++;
  19. index = index + this.simplePrefix.length();
  20. }
  21. else {
  22. index++;
  23. }
  24. }
  25. return -1;
  26. }