diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/cache/CacheStats.java b/hutool-core/src/main/java/cn/hutool/v7/core/cache/CacheStats.java deleted file mode 100644 index 577115e7e9..0000000000 --- a/hutool-core/src/main/java/cn/hutool/v7/core/cache/CacheStats.java +++ /dev/null @@ -1,214 +0,0 @@ -package cn.hutool.v7.core.cache; - -import java.io.Serializable; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.LongAdder; - -/** - * 缓存统计信息 - * - * @author Nic - */ -public class CacheStats implements Serializable { - private static final long serialVersionUID = 1L; - - private final LongAdder hitCount; - private final LongAdder missCount; - private final LongAdder loadSuccessCount; - private final LongAdder loadFailureCount; - private final LongAdder evictionCount; - private final LongAdder totalLoadTime; // 纳秒 - private final AtomicLong cacheSize; - private final long startTime; - - /** - * 构建器模式 - */ - public static class Builder { - private final CacheStats stats; - - public Builder() { - this.stats = new CacheStats(); - } - - public Builder hitCount(long hitCount) { - stats.hitCount.add(hitCount); - return this; - } - - public Builder missCount(long missCount) { - stats.missCount.add(missCount); - return this; - } - - public Builder loadSuccessCount(long loadSuccessCount) { - stats.loadSuccessCount.add(loadSuccessCount); - return this; - } - - public Builder loadFailureCount(long loadFailureCount) { - stats.loadFailureCount.add(loadFailureCount); - return this; - } - - public Builder evictionCount(long evictionCount) { - stats.evictionCount.add(evictionCount); - return this; - } - - public Builder totalLoadTime(long totalLoadTime) { - stats.totalLoadTime.add(totalLoadTime); - return this; - } - - public Builder cacheSize(long cacheSize) { - stats.cacheSize.set(cacheSize); - return this; - } - - public CacheStats build() { - return stats; - } - } - - public CacheStats() { - this.hitCount = new LongAdder(); - this.missCount = new LongAdder(); - this.loadSuccessCount = new LongAdder(); - this.loadFailureCount = new LongAdder(); - this.evictionCount = new LongAdder(); - this.totalLoadTime = new LongAdder(); - this.cacheSize = new AtomicLong(0); - this.startTime = System.currentTimeMillis(); - } - - // ========== 统计计算方法 ========== - - /** - * 获取命中率 - */ - public double getHitRate() { - long requestCount = hitCount.longValue() + missCount.longValue(); - return requestCount == 0 ? 1.0 : (double) hitCount.longValue() / requestCount; - } - - /** - * 获取未命中率 - */ - public double getMissRate() { - long requestCount = hitCount.longValue() + missCount.longValue(); - return requestCount == 0 ? 0.0 : (double) missCount.longValue() / requestCount; - } - - /** - * 获取平均加载时间(毫秒) - */ - public double getAverageLoadTime() { - long total = totalLoadTime.longValue(); - long success = loadSuccessCount.longValue(); - return success == 0 ? 0.0 : (total / 1_000_000.0) / success; - } - - /** - * 获取加载失败率 - */ - public double getLoadFailureRate() { - long totalLoads = loadSuccessCount.longValue() + loadFailureCount.longValue(); - return totalLoads == 0 ? 0.0 : (double) loadFailureCount.longValue() / totalLoads; - } - - /** - * 获取缓存运行时间(秒) - */ - public long getRuntimeSeconds() { - return (System.currentTimeMillis() - startTime) / 1000; - } - - // ========== Getter方法 ========== - - public long getHitCount() { - return hitCount.longValue(); - } - - public long getMissCount() { - return missCount.longValue(); - } - - public long getLoadSuccessCount() { - return loadSuccessCount.longValue(); - } - - public long getLoadFailureCount() { - return loadFailureCount.longValue(); - } - - public long getEvictionCount() { - return evictionCount.longValue(); - } - - public long getTotalLoadTime() { - return totalLoadTime.longValue(); - } - - public long getCacheSize() { - return cacheSize.get(); - } - - public long getStartTime() { - return startTime; - } - - /** - * 记录一次命中 - */ - public void recordHit() { - hitCount.increment(); - } - - /** - * 记录一次未命中 - */ - public void recordMiss() { - missCount.increment(); - } - - /** - * 记录一次成功的加载 - */ - public void recordLoadSuccess(long loadTime) { - loadSuccessCount.increment(); - totalLoadTime.add(loadTime); - } - - /** - * 记录一次失败的加载 - */ - public void recordLoadFailure() { - loadFailureCount.increment(); - } - - /** - * 记录一次驱逐 - */ - public void recordEviction() { - evictionCount.increment(); - } - - /** - * 更新缓存大小 - */ - public void setCacheSize(long size) { - cacheSize.set(size); - } - - @Override - public String toString() { - return String.format( - "CacheStats{hitRate=%.2f%%, hits=%d, misses=%d, loadSuccess=%d, loadFailure=%d, " + - "evictions=%d, avgLoadTime=%.2fms, size=%d, runtime=%ds}", - getHitRate() * 100, getHitCount(), getMissCount(), getLoadSuccessCount(), - getLoadFailureCount(), getEvictionCount(), getAverageLoadTime(), - getCacheSize(), getRuntimeSeconds() - ); - } -} diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/cache/SmartCache.java b/hutool-core/src/main/java/cn/hutool/v7/core/cache/SmartCache.java deleted file mode 100644 index 2f11dc8057..0000000000 --- a/hutool-core/src/main/java/cn/hutool/v7/core/cache/SmartCache.java +++ /dev/null @@ -1,91 +0,0 @@ -package cn.hutool.v7.core.cache; - -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; - -/** - * 智能缓存接口 - 扩展Hutool标准缓存功能 - * - *

提供多级缓存、异步刷新、缓存预热等高级功能

- * - * @author Nic - */ -public interface SmartCache extends Cache { - - /** - * 批量获取缓存项 - * - * @param keys 键集合 - * @return 键值对映射 - */ - Map getAll(Collection keys); - - /** - * 批量放入缓存项 - * - * @param map 键值对映射 - */ - void putAll(Map map); - - /** - * 异步刷新缓存项 - * - * @param key 缓存键 - * @return CompletableFuture包装的缓存值 - */ - CompletableFuture refreshAsync(K key); - - /** - * 缓存预热 - * - * @param keys 需要预热的键集合 - * @return 预热成功的数量 - */ - int warmUp(Collection keys); - - /** - * 原子操作:如果不存在则计算并放入 - * - * @param key 缓存键 - * @param mappingFunction 映射函数 - * @return 缓存值 - */ - V computeIfAbsent(K key, Function mappingFunction); - - /** - * 原子操作:如果存在则重新计算 - * - * @param key 缓存键 - * @param remappingFunction 重新映射函数 - * @return 新的缓存值 - */ - V computeIfPresent(K key, Function remappingFunction); - - /** - * 获取缓存统计信息 - * - * @return 缓存统计 - */ - CacheStats getStats(); - - /** - * 清除所有统计信息 - */ - void clearStats(); - - /** - * 获取缓存名称 - * - * @return 缓存名称 - */ - String getName(); - - /** - * 设置缓存名称 - * - * @param name 缓存名称 - */ - void setName(String name); -} diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/cache/SmartCacheBuilder.java b/hutool-core/src/main/java/cn/hutool/v7/core/cache/SmartCacheBuilder.java deleted file mode 100644 index 9313dbcdae..0000000000 --- a/hutool-core/src/main/java/cn/hutool/v7/core/cache/SmartCacheBuilder.java +++ /dev/null @@ -1,122 +0,0 @@ -package cn.hutool.v7.core.cache; - -import cn.hutool.v7.core.cache.impl.SmartCacheImpl; -import cn.hutool.v7.core.text.StrUtil; - -import java.time.Duration; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Function; - -/** - * 智能缓存构建器 - * - * @author Nic - */ -public class SmartCacheBuilder { - - // 必需参数 - private final Cache cache; - - // 可选参数 - private String name = "SmartCache"; - private boolean enableStats = true; - private boolean enableAsyncRefresh = false; - private int warmUpBatchSize = 100; - private Duration refreshTimeout = Duration.ofSeconds(30); - private ExecutorService refreshExecutor; - private Function cacheLoader; - - /** - * 私有构造器 - */ - private SmartCacheBuilder(Cache cache) { - this.cache = cache; - } - - /** - * 创建构建器 - */ - public static SmartCacheBuilder of(Cache cache) { - return new SmartCacheBuilder<>(cache); - } - - /** - * 设置缓存名称 - */ - public SmartCacheBuilder name(String name) { - this.name = StrUtil.defaultIfBlank(name, "SmartCache"); - return this; - } - - /** - * 启用统计 - */ - public SmartCacheBuilder enableStats(boolean enableStats) { - this.enableStats = enableStats; - return this; - } - - /** - * 启用异步刷新 - */ - public SmartCacheBuilder enableAsyncRefresh(boolean enableAsyncRefresh) { - this.enableAsyncRefresh = enableAsyncRefresh; - return this; - } - - /** - * 设置预热批次大小 - */ - public SmartCacheBuilder warmUpBatchSize(int warmUpBatchSize) { - this.warmUpBatchSize = Math.max(1, warmUpBatchSize); - return this; - } - - /** - * 设置刷新超时时间 - */ - public SmartCacheBuilder refreshTimeout(Duration refreshTimeout) { - this.refreshTimeout = refreshTimeout; - return this; - } - - /** - * 设置刷新线程池 - */ - public SmartCacheBuilder refreshExecutor(ExecutorService refreshExecutor) { - this.refreshExecutor = refreshExecutor; - return this; - } - - /** - * 设置缓存加载器 - */ - public SmartCacheBuilder cacheLoader(Function cacheLoader) { - this.cacheLoader = cacheLoader; - return this; - } - - /** - * 构建智能缓存 - */ - public SmartCache build() { - // 确保有刷新线程池(如果需要异步刷新) - if (enableAsyncRefresh && refreshExecutor == null) { - refreshExecutor = Executors.newFixedThreadPool( - Math.max(2, Runtime.getRuntime().availableProcessors() / 2) - ); - } - - return new SmartCacheImpl<>( - cache, - name, - enableStats, - enableAsyncRefresh, - warmUpBatchSize, - refreshTimeout, - refreshExecutor, - cacheLoader - ); - } -} diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/cache/SmartCacheUtil.java b/hutool-core/src/main/java/cn/hutool/v7/core/cache/SmartCacheUtil.java deleted file mode 100644 index f4e439ff3e..0000000000 --- a/hutool-core/src/main/java/cn/hutool/v7/core/cache/SmartCacheUtil.java +++ /dev/null @@ -1,116 +0,0 @@ -package cn.hutool.v7.core.cache; - -import cn.hutool.v7.core.cache.impl.LRUCache; - -/** - * 智能缓存工具类 - * - * @author Nic - */ -public class SmartCacheUtil { - - private SmartCacheUtil() { - // 工具类,禁止实例化 - } - - /** - * 创建LRU智能缓存 - */ - public static SmartCache newLRUSmartCache(int capacity) { - return (SmartCache) SmartCacheBuilder.of(CacheUtil.newLRUCache(capacity)) - .name("LRU-SmartCache") - .build(); - } - - /** - * 创建LFU智能缓存 - */ - public static SmartCache newLFUSmartCache(int capacity) { - return (SmartCache) SmartCacheBuilder.of(CacheUtil.newLFUCache(capacity)) - .name("LFU-SmartCache") - .build(); - } - - /** - * 创建FIFO智能缓存 - */ - public static SmartCache newFIFOSmartCache(int capacity) { - return (SmartCache) SmartCacheBuilder.of(CacheUtil.newFIFOCache(capacity)) - .name("FIFO-SmartCache") - .build(); - } - - /** - * 创建带加载器的智能缓存 - */ - public static SmartCache newSmartCache( - Cache cache, - java.util.function.Function loader) { - - return SmartCacheBuilder.of(cache) - .cacheLoader(loader) - .enableAsyncRefresh(true) - .enableStats(true) - .build(); - } - - /** - * 创建定时过期的智能缓存 - */ - public static SmartCache newTimedSmartCache( - int capacity, - long timeout, - java.util.function.Function loader) { - - Cache cache = new LRUCache<>(capacity, timeout) { - @Override - public boolean isFull() { - return this.cacheMap.size() >= capacity; - } - }; - - return SmartCacheBuilder.of(cache) - .name("Timed-SmartCache") - .cacheLoader(loader) - .enableStats(true) - .build(); - } - - /** - * 获取缓存的详细统计信息 - */ - public static String getDetailedStats(SmartCache cache) { - if (cache == null) { - return "Cache is null"; - } - - try { - CacheStats stats = cache.getStats(); - return String.format( - "Cache: %s\n" + - " Size: %d / %d\n" + - " Hit Rate: %.2f%%\n" + - " Hits: %d\n" + - " Misses: %d\n" + - " Load Success: %d\n" + - " Load Failure: %d\n" + - " Avg Load Time: %.2fms\n" + - " Evictions: %d\n" + - " Runtime: %ds", - cache.getName(), - cache.size(), - cache.capacity(), - stats.getHitRate() * 100, - stats.getHitCount(), - stats.getMissCount(), - stats.getLoadSuccessCount(), - stats.getLoadFailureCount(), - stats.getAverageLoadTime(), - stats.getEvictionCount(), - stats.getRuntimeSeconds() - ); - } catch (Exception e) { - return "Unable to get stats: " + e.getMessage(); - } - } -} diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/cache/impl/SmartCacheImpl.java b/hutool-core/src/main/java/cn/hutool/v7/core/cache/impl/SmartCacheImpl.java index 162de67573..daa89c241e 100644 --- a/hutool-core/src/main/java/cn/hutool/v7/core/cache/impl/SmartCacheImpl.java +++ b/hutool-core/src/main/java/cn/hutool/v7/core/cache/impl/SmartCacheImpl.java @@ -1,14 +1,16 @@ package cn.hutool.v7.core.cache.impl; import cn.hutool.v7.core.cache.Cache; -import cn.hutool.v7.core.cache.CacheStats; -import cn.hutool.v7.core.cache.SmartCache; +import cn.hutool.v7.core.cache.smart.CacheStats; +import cn.hutool.v7.core.cache.smart.SmartCache; import cn.hutool.v7.core.collection.CollUtil; import cn.hutool.v7.core.collection.iter.CopiedIter; import cn.hutool.v7.core.collection.partition.Partition; +import cn.hutool.v7.core.exception.HutoolException; import cn.hutool.v7.core.func.SerSupplier; import cn.hutool.v7.core.map.MapUtil; import cn.hutool.v7.core.text.StrUtil; + import java.time.Duration; import java.util.*; import java.util.concurrent.*; @@ -18,6 +20,8 @@ import java.util.function.Function; /** * 智能缓存实现 * + * @param 缓存键类型 + * @param 缓存值类型 * @author Nic */ public class SmartCacheImpl implements SmartCache { @@ -42,17 +46,26 @@ public class SmartCacheImpl implements SmartCache { private final Map> pendingRefreshes = new ConcurrentHashMap<>(); /** - * 构造器 + * 构造函数 + * + * @param delegate 底层缓存实现 + * @param name 缓存名称 + * @param enableStats 是否启用统计信息 + * @param enableAsyncRefresh 是否启用异步刷新 + * @param warmUpBatchSize warmUpBatchSize + * @param refreshTimeout 刷新超时时间 + * @param refreshExecutor 刷新执行器 + * @param cacheLoader 缓存加载器 */ public SmartCacheImpl( - Cache delegate, - String name, - boolean enableStats, - boolean enableAsyncRefresh, - int warmUpBatchSize, - Duration refreshTimeout, - ExecutorService refreshExecutor, - Function cacheLoader) { + final Cache delegate, + final String name, + final boolean enableStats, + final boolean enableAsyncRefresh, + final int warmUpBatchSize, + final Duration refreshTimeout, + final ExecutorService refreshExecutor, + final Function cacheLoader) { this.delegate = delegate; this.name = name; @@ -68,7 +81,7 @@ public class SmartCacheImpl implements SmartCache { // ========== 实现Cache接口方法 ========== @Override - public void put(K key, V object, long timeout) { + public void put(final K key, final V object, final long timeout) { lock.writeLock().lock(); try { delegate.put(key, object, timeout); @@ -81,12 +94,12 @@ public class SmartCacheImpl implements SmartCache { } @Override - public void put(K key, V object) { + public void put(final K key, final V object) { put(key, object, 0); } @Override - public V get(K key, boolean isUpdateLastAccess) { + public V get(final K key, final boolean isUpdateLastAccess) { lock.readLock().lock(); try { V value = delegate.get(key, isUpdateLastAccess); @@ -99,16 +112,16 @@ public class SmartCacheImpl implements SmartCache { // 如果有缓存加载器,尝试加载 if (cacheLoader != null) { - long startTime = System.nanoTime(); + final long startTime = System.nanoTime(); try { value = cacheLoader.apply(key); if (value != null) { delegate.put(key, value); stats.recordLoadSuccess(System.nanoTime() - startTime); } - } catch (Exception e) { + } catch (final Exception e) { stats.recordLoadFailure(); - throw new CacheException("Failed to load cache value for key: " + key, e); + throw new HutoolException("Failed to load cache value for key: " + key, e); } } } @@ -121,10 +134,11 @@ public class SmartCacheImpl implements SmartCache { } @Override - public V get(K key) { + public V get(final K key) { return get(key, false); } + @SuppressWarnings("NullableProblems") @Override public Iterator iterator() { return delegate.iterator(); @@ -134,7 +148,7 @@ public class SmartCacheImpl implements SmartCache { public int prune() { lock.writeLock().lock(); try { - int pruned = delegate.prune(); + final int pruned = delegate.prune(); if (enableStats && pruned > 0) { for (int i = 0; i < pruned; i++) { stats.recordEviction(); @@ -158,7 +172,7 @@ public class SmartCacheImpl implements SmartCache { } @Override - public void remove(K key) { + public void remove(final K key) { lock.writeLock().lock(); try { delegate.remove(key); @@ -225,7 +239,7 @@ public class SmartCacheImpl implements SmartCache { } @Override - public boolean containsKey(K key) { + public boolean containsKey(final K key) { lock.readLock().lock(); try { return delegate.containsKey(key); @@ -237,17 +251,17 @@ public class SmartCacheImpl implements SmartCache { // ========== 实现SmartCache接口方法 ========== @Override - public Map getAll(Collection keys) { + public Map getAll(final Collection keys) { if (CollUtil.isEmpty(keys)) { return Collections.emptyMap(); } lock.readLock().lock(); try { - Map result = new HashMap<>(keys.size()); + final Map result = new HashMap<>(keys.size()); - for (K key : keys) { - V value = get(key); + for (final K key : keys) { + final V value = get(key); if (value != null) { result.put(key, value); } @@ -260,14 +274,14 @@ public class SmartCacheImpl implements SmartCache { } @Override - public void putAll(Map map) { + public void putAll(final Map map) { if (MapUtil.isEmpty(map)) { return; } lock.writeLock().lock(); try { - for (Map.Entry entry : map.entrySet()) { + for (final Map.Entry entry : map.entrySet()) { delegate.put(entry.getKey(), entry.getValue()); } @@ -280,7 +294,7 @@ public class SmartCacheImpl implements SmartCache { } @Override - public CompletableFuture refreshAsync(K key) { + public CompletableFuture refreshAsync(final K key) { if (!enableAsyncRefresh) { throw new UnsupportedOperationException("Async refresh is not enabled"); } @@ -290,15 +304,15 @@ public class SmartCacheImpl implements SmartCache { } // 检查是否已经有正在进行的刷新 - CompletableFuture pending = pendingRefreshes.get(key); + final CompletableFuture pending = pendingRefreshes.get(key); if (pending != null) { return pending; } CompletableFuture future = CompletableFuture.supplyAsync(() -> { try { - long startTime = System.nanoTime(); - V newValue = cacheLoader.apply(key); + final long startTime = System.nanoTime(); + final V newValue = cacheLoader.apply(key); if (newValue != null) { lock.writeLock().lock(); @@ -313,7 +327,7 @@ public class SmartCacheImpl implements SmartCache { } return newValue; - } catch (Exception e) { + } catch (final Exception e) { if (enableStats) { stats.recordLoadFailure(); } @@ -335,26 +349,26 @@ public class SmartCacheImpl implements SmartCache { } @Override - public int warmUp(Collection keys) { + public int warmUp(final Collection keys) { if (cacheLoader == null || CollUtil.isEmpty(keys)) { return 0; } int warmedUp = 0; - Collection> batches = new Partition<>(new ArrayList<>(keys), warmUpBatchSize); + final Collection> batches = new Partition<>(new ArrayList<>(keys), warmUpBatchSize); - for (List batch : batches) { + for (final List batch : batches) { lock.writeLock().lock(); try { - for (K key : batch) { + for (final K key : batch) { if (!delegate.containsKey(key)) { try { - V value = cacheLoader.apply(key); + final V value = cacheLoader.apply(key); if (value != null) { delegate.put(key, value); warmedUp++; } - } catch (Exception e) { + } catch (final Exception e) { // 忽略单个键的加载失败,继续处理其他键 } } @@ -372,12 +386,12 @@ public class SmartCacheImpl implements SmartCache { } @Override - public V computeIfAbsent(K key, Function mappingFunction) { + public V computeIfAbsent(final K key, final Function mappingFunction) { lock.writeLock().lock(); try { V value = delegate.get(key); if (value == null && mappingFunction != null) { - long startTime = System.nanoTime(); + final long startTime = System.nanoTime(); try { value = mappingFunction.apply(key); if (value != null) { @@ -388,11 +402,11 @@ public class SmartCacheImpl implements SmartCache { stats.setCacheSize(delegate.size()); } } - } catch (Exception e) { + } catch (final Exception e) { if (enableStats) { stats.recordLoadFailure(); } - throw new CacheException("Failed to compute value for key: " + key, e); + throw new HutoolException("Failed to compute value for key: " + key, e); } } @@ -403,13 +417,13 @@ public class SmartCacheImpl implements SmartCache { } @Override - public V computeIfPresent(K key, Function remappingFunction) { + public V computeIfPresent(final K key, final Function remappingFunction) { lock.writeLock().lock(); try { if (delegate.containsKey(key) && remappingFunction != null) { - long startTime = System.nanoTime(); + final long startTime = System.nanoTime(); try { - V newValue = remappingFunction.apply(key); + final V newValue = remappingFunction.apply(key); if (newValue != null) { delegate.put(key, newValue); @@ -418,11 +432,11 @@ public class SmartCacheImpl implements SmartCache { } } return newValue; - } catch (Exception e) { + } catch (final Exception e) { if (enableStats) { stats.recordLoadFailure(); } - throw new CacheException("Failed to compute value for key: " + key, e); + throw new HutoolException("Failed to compute value for key: " + key, e); } } return null; @@ -455,7 +469,7 @@ public class SmartCacheImpl implements SmartCache { lock.writeLock().lock(); try { // 创建新的统计实例,保留缓存大小 - long currentSize = stats.getCacheSize(); + final long currentSize = stats.getCacheSize(); stats.setCacheSize(currentSize); } finally { lock.writeLock().unlock(); @@ -468,19 +482,21 @@ public class SmartCacheImpl implements SmartCache { } @Override - public void setName(String name) { + public void setName(final String name) { this.name = StrUtil.defaultIfBlank(name, "SmartCache"); } /** * 获取底层缓存 + * + * @return 底层缓存实例 */ public Cache getDelegate() { return delegate; } @Override - public V get(K key, boolean isUpdateLastAccess, long timeout, SerSupplier valueFactory) { + public V get(final K key, final boolean isUpdateLastAccess, final long timeout, final SerSupplier valueFactory) { if (key == null) { throw new NullPointerException("Key must not be null"); } @@ -502,7 +518,7 @@ public class SmartCacheImpl implements SmartCache { value = delegate.get(key, isUpdateLastAccess); if (value == null) { // 记录加载开始时间,用于统计 - long loadStartTime = System.nanoTime(); + final long loadStartTime = System.nanoTime(); try { // 调用工厂方法创建新值 value = valueFactory.get(); @@ -527,13 +543,13 @@ public class SmartCacheImpl implements SmartCache { } // 注意:此时并未将null值存入缓存,下次请求仍会触发加载 } - } catch (Exception e) { + } catch (final Exception e) { if (enableStats) { stats.recordLoadFailure(); } // 可以根据需要决定是抛出异常,还是返回null。 // 为了保持接口的健壮性,这里将异常包装后抛出。 - throw new CacheException("Failed to load value for key: " + key, e); + throw new HutoolException("Failed to load value for key: " + key, e); } } // 无论新值是否由当前线程创建,写锁块结束时,value变量中已经有了最终结果。 @@ -557,17 +573,4 @@ public class SmartCacheImpl implements SmartCache { } return new CacheObjIterator<>(copiedIterator); } - - /** - * 自定义缓存异常 - */ - public static class CacheException extends RuntimeException { - public CacheException(String message) { - super(message); - } - - public CacheException(String message, Throwable cause) { - super(message, cause); - } - } } diff --git a/hutool-core/src/test/java/cn/hutool/v7/core/cache/SmartCacheBasicTest.java b/hutool-core/src/test/java/cn/hutool/v7/core/cache/SmartCacheBasicTest.java index 8ce7abf432..9ad9920542 100644 --- a/hutool-core/src/test/java/cn/hutool/v7/core/cache/SmartCacheBasicTest.java +++ b/hutool-core/src/test/java/cn/hutool/v7/core/cache/SmartCacheBasicTest.java @@ -1,5 +1,8 @@ package cn.hutool.v7.core.cache; +import cn.hutool.v7.core.cache.smart.SmartCache; +import cn.hutool.v7.core.cache.smart.SmartCacheBuilder; +import cn.hutool.v7.core.cache.smart.SmartCacheUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.DisplayName;