Guava Cache源码:CacheBuilderSpec ValueParser分析

目录

1.ValueParser顶层接口

2.ValueParser继承层次结构

3.ValueParser应用


这篇文章主要分析Guava Cache中ValueParser类的源码实现,学习和借鉴其简单优雅的设计方法,加以记录和沉淀,想要学习Guava Cache支持特性的进一步源码分析,请移步:Guava Cache源码:从特性说起剖析Guava Cache源码实现

1.ValueParser顶层接口

ValueParser顶层接口,定义解析key,value的方法,并设置到CacheBuilderSpec中:

  private interface ValueParser {
    void parse(CacheBuilderSpec spec, String key, @Nullable String value);
  }

2.ValueParser继承层次结构

3.ValueParser应用

CacheBuilderSpec解析过程如下,通过应用策略模式,根据不同的key调用不同的解析器,进而构造完成CacheBuilderSpec对象

 /** Splits each key-value pair. */
  private static final Splitter KEYS_SPLITTER = Splitter.on(',').trimResults();

  /** Splits the key from the value. */
  private static final Splitter KEY_VALUE_SPLITTER = Splitter.on('=').trimResults();

  /** Map of names to ValueParser. */
  private static final ImmutableMap VALUE_PARSERS =
      ImmutableMap.builder()
          .put("initialCapacity", new InitialCapacityParser())
          .put("maximumSize", new MaximumSizeParser())
          .put("maximumWeight", new MaximumWeightParser())
          .put("concurrencyLevel", new ConcurrencyLevelParser())
          .put("weakKeys", new KeyStrengthParser(Strength.WEAK))
          .put("softValues", new ValueStrengthParser(Strength.SOFT))
          .put("weakValues", new ValueStrengthParser(Strength.WEAK))
          .put("recordStats", new RecordStatsParser())
          .put("expireAfterAccess", new AccessDurationParser())
          .put("expireAfterWrite", new WriteDurationParser())
          .put("refreshAfterWrite", new RefreshDurationParser())
          .put("refreshInterval", new RefreshDurationParser())
          .build();

  @VisibleForTesting Integer initialCapacity;
  @VisibleForTesting Long maximumSize;
  @VisibleForTesting Long maximumWeight;
  @VisibleForTesting Integer concurrencyLevel;
  @VisibleForTesting Strength keyStrength;
  @VisibleForTesting Strength valueStrength;
  @VisibleForTesting Boolean recordStats;
  @VisibleForTesting long writeExpirationDuration;
  @VisibleForTesting TimeUnit writeExpirationTimeUnit;
  @VisibleForTesting long accessExpirationDuration;
  @VisibleForTesting TimeUnit accessExpirationTimeUnit;
  @VisibleForTesting long refreshDuration;
  @VisibleForTesting TimeUnit refreshTimeUnit;

  /** Specification; used for toParseableString(). */
  private final String specification;

  private CacheBuilderSpec(String specification) {
    this.specification = specification;
  }

  /**
   * Creates a CacheBuilderSpec from a string.
   *
   * @param cacheBuilderSpecification the string form
   */
  public static CacheBuilderSpec parse(String cacheBuilderSpecification) {
    CacheBuilderSpec spec = new CacheBuilderSpec(cacheBuilderSpecification);
    if (!cacheBuilderSpecification.isEmpty()) {
      for (String keyValuePair : KEYS_SPLITTER.split(cacheBuilderSpecification)) {
        List keyAndValue = ImmutableList.copyOf(KEY_VALUE_SPLITTER.split(keyValuePair));
        checkArgument(!keyAndValue.isEmpty(), "blank key-value pair");
        checkArgument(
            keyAndValue.size() <= 2,
            "key-value pair %s with more than one equals sign",
            keyValuePair);

        // Find the ValueParser for the current key.
        String key = keyAndValue.get(0);
        ValueParser valueParser = VALUE_PARSERS.get(key);
        checkArgument(valueParser != null, "unknown key %s", key);

        String value = keyAndValue.size() == 1 ? null : keyAndValue.get(1);
        valueParser.parse(spec, key, value);
      }
    }

    return spec;
  }

最后通过CacheBuilderSpec来构造CacheBuilder:

  /**
   * Returns a CacheBuilder configured according to this instance's specification.
   */
  CacheBuilder toCacheBuilder() {
    CacheBuilder builder = CacheBuilder.newBuilder();
    if (initialCapacity != null) {
      builder.initialCapacity(initialCapacity);
    }
    if (maximumSize != null) {
      builder.maximumSize(maximumSize);
    }
    if (maximumWeight != null) {
      builder.maximumWeight(maximumWeight);
    }
    if (concurrencyLevel != null) {
      builder.concurrencyLevel(concurrencyLevel);
    }
    if (keyStrength != null) {
      switch (keyStrength) {
        case WEAK:
          builder.weakKeys();
          break;
        default:
          throw new AssertionError();
      }
    }
    if (valueStrength != null) {
      switch (valueStrength) {
        case SOFT:
          builder.softValues();
          break;
        case WEAK:
          builder.weakValues();
          break;
        default:
          throw new AssertionError();
      }
    }
    if (recordStats != null && recordStats) {
      builder.recordStats();
    }
    if (writeExpirationTimeUnit != null) {
      builder.expireAfterWrite(writeExpirationDuration, writeExpirationTimeUnit);
    }
    if (accessExpirationTimeUnit != null) {
      builder.expireAfterAccess(accessExpirationDuration, accessExpirationTimeUnit);
    }
    if (refreshTimeUnit != null) {
      builder.refreshAfterWrite(refreshDuration, refreshTimeUnit);
    }

    return builder;
  }

你可能感兴趣的:(guava,cache,java,后端,缓存)