当前位置: 首页 > 工具软件 > CacheManager > 使用案例 >

Spring Cache基础组件 CacheManager

钱运浩
2023-12-01

相关阅读

简介

缓存管理器,管理各种缓存组件;

核心代码

/**
 * 根据缓存标识符获取缓存
 */
@Nullable
Cache getCache(String name);

/**
 * 获取此缓存管理器已知的缓存标识符集合
 */
Collection<String> getCacheNames();

实现子类

public interface CacheManager
    public class NoOpCacheManager implements CacheManager
    public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderAware
    public abstract class AbstractCacheManager implements CacheManager, InitializingBean
        public class SimpleCacheManager extends AbstractCacheManager
        public abstract class AbstractTransactionSupportingCacheManager extends AbstractCacheManager
            public class RedisCacheManager extends AbstractTransactionSupportingCacheManager

NoOpCacheManager

简介

基于NoOpCache实现的缓存管理器;
没有真正存储缓存,适用于禁止缓存的场景;

核心代码

// 缓存集合
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<>(16);
// 缓存标识符集合
private final Set<String> cacheNames = new LinkedHashSet<>(16);


/**
 * 根据缓存标识符获取缓存
 */
@Nullable
public Cache getCache(String name) {
    Cache cache = this.caches.get(name);
    if (cache == null) {
        // 若缓存标识符对应的缓存不存在,则创建对应的NoOpCache并缓存,方便下次直接获取
        this.caches.computeIfAbsent(name, key -> new NoOpCache(name));
        synchronized (this.cacheNames) {
            // 缓存当前缓存标识符
            this.cacheNames.add(name);
        }
    }
    return this.caches.get(name);
}

/**
 * 获取此缓存管理器已知的缓存标识符集合
 */
public Collection<String> getCacheNames() {
    synchronized (this.cacheNames) {
        // 返回已存在的缓存标识符的不可变Set
        return Collections.unmodifiableSet(this.cacheNames);
    }
}

ConcurrentMapCacheManager

简介

基于ConcurrentMapCache实现的缓存管理器;
支持静态模式,即预定义缓存名称集合,不再支持动态创建缓存;

核心代码

// 缓存集合
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<>(16);
// 允许动态创建缓存标识,默认支持
private boolean dynamic = true;
// 允许null值标识,默认允许
private boolean allowNullValues = true;
// 存储值的拷贝还是引用,默认存储引用
private boolean storeByValue = false;
// 序列化器
@Nullable
private SerializationDelegate serialization;


/**
 * 根据缓存标识符配置生成缓存
 * 如果入参有效,不再支持动态创建缓存
 */
public void setCacheNames(@Nullable Collection<String> cacheNames) {
    if (cacheNames != null) {
        for (String name : cacheNames) {
            this.cacheMap.put(name, createConcurrentMapCache(name));
        }
        // 根据配置生成缓存后,不再支持动态创建缓存
        this.dynamic = false;
    }
    else {
        // 无效参数,支持动态创建缓存
        this.dynamic = true;
    }
}

/**
 * 获取此缓存管理器已知的缓存标识符集合
 */
@Override
public Collection<String> getCacheNames() {
    return Collections.unmodifiableSet(this.cacheMap.keySet());
}

/**
 * 根据缓存标识符获取缓存
 */
@Nullable
public Cache getCache(String name) {
    Cache cache = this.cacheMap.get(name);
    if (cache == null && this.dynamic) {
        // 如果缓存不存在且支持动态创建缓存
        synchronized (this.cacheMap) {
            // 再次确认,防止并发创建
            cache = this.cacheMap.get(name);
            if (cache == null) {
                // 动态创建缓存
                cache = createConcurrentMapCache(name);
                this.cacheMap.put(name, cache);
            }
        }
    }
    return cache;
}

/**
 * 重置缓存集合
 */
private void recreateCaches() {
     for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) {
        entry.setValue(createConcurrentMapCache(entry.getKey()));
     }
}

/**
 * 创建ConcurrentMapCache
 */
protected Cache createConcurrentMapCache(String name) {
     SerializationDelegate actualSerialization = (isStoreByValue() ? this.serialization : null);
     return new ConcurrentMapCache(name, new ConcurrentHashMap<>(256), isAllowNullValues(), actualSerialization);
}

AbstractCacheManager

简介

实现CacheManager接口的抽象基础类,在内部缓存不变化的静态环境很有用;

核心代码

// 缓存集合
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<>(16);
// 缓存标识符集合
private volatile Set<String> cacheNames = Collections.emptySet();


/**
 * 初始化缓存
 * 算法模板
 */
public void initializeCaches() {
    // 加载缓存静态配置
    Collection<? extends Cache> caches = loadCaches();
    synchronized (this.cacheMap) {
        // 清空缓存数据
        this.cacheNames = Collections.emptySet();
        this.cacheMap.clear();
        // 更新缓存数据
        Set<String> cacheNames = new LinkedHashSet<>(caches.size());
        for (Cache cache : caches) {
            String name = cache.getName();
            this.cacheMap.put(name, decorateCache(cache));
            cacheNames.add(name);
        }
        this.cacheNames = Collections.unmodifiableSet(cacheNames);
    }
}

/**
 * 加载缓存初始配置,如果没有则返回空集合
 * 算法细节,由子类实现
 */
protected abstract Collection<? extends Cache> loadCaches();

/**
 * 根据缓存标识符获取缓存,支持缓存的懒创建
 */
@Nullable
public Cache getCache(String name) {
    // Quick check for existing cache...
    Cache cache = this.cacheMap.get(name);
    if (cache != null) {
        // 如果存在直接返回
        return cache;
    }

    // 若支持按需创建缓存,由子类实现算法细节
    // The provider may support on-demand cache creation...
    Cache missingCache = getMissingCache(name);
    if (missingCache != null) {
        // Fully synchronize now for missing cache registration
        // 保存新缓存
        synchronized (this.cacheMap) {
            cache = this.cacheMap.get(name);
            if (cache == null) {
                // 若有必要,装饰缓存
                cache = decorateCache(missingCache);
                // 加入新缓存
                this.cacheMap.put(name, cache);
                // 更新缓存标识符集合,更新动作都在cacheMap同步代码块中
                updateCacheNames(name);
            }
        }
    }
    return cache;
}

/**
 * 更新缓存标识符集合,保证cacheNames不可变
 */
private void updateCacheNames(String name) {
    Set<String> cacheNames = new LinkedHashSet<>(this.cacheNames);
    cacheNames.add(name);
    this.cacheNames = Collections.unmodifiableSet(cacheNames);
}

/**
 * 获取此缓存管理器已知的缓存标识符集合
 */
public Collection<String> getCacheNames() {
    return this.cacheNames;
}

/**
 * 根据缓存标识符查找缓存,不支持缓存的懒创建
 */
@Nullable
protected final Cache lookupCache(String name) {
    return this.cacheMap.get(name);
}

/**
 * 装饰缓存
 * 子类可重写实现算法细节
 */
protected Cache decorateCache(Cache cache) {
     return cache;
}

/**
 * 根据缓存标识符查找缺失缓存,若不存在或者无法创建则返回null
 * 子类可重写实现算法细节
 */
@Nullable
protected Cache getMissingCache(String name) {
    return null;
}

SimpleCacheManager

简介

基于给定缓存集合的简单缓存管理器,可用于测试或者简单的缓存生命;

核心代码

// 缓存集合
private Collection<? extends Cache> caches = Collections.emptySet();


/**
 * 设置缓存集合
 */
public void setCaches(Collection<? extends Cache> caches) {
    this.caches = caches;
}

/**
 * 加载缓存初始配置
 */
protected Collection<? extends Cache> loadCaches() {
    return this.caches;
}

AbstractTransactionSupportingCacheManager

简介

支持使用TransactionAwareCacheDecorator装饰原Cache以支持Spring事务的缓存管理器;

核心代码

// 是否支持Spring事务
// 若支持,则缓存操作等事务提交后才生效
private boolean transactionAware = false;


/**
 * 装饰Cache,返回支持Spring事务的Cache
 */
protected Cache decorateCache(Cache cache) {
    return (isTransactionAware() ? new TransactionAwareCacheDecorator(cache) : cache);
}

RedisCacheManager

简介

基于Redis实现的缓存管理器;

核心代码

// Redis操作
private final RedisCacheWriter cacheWriter;
// 缓存默认配置
private final RedisCacheConfiguration defaultCacheConfig;
// 缓存初始化配置
private final Map<String, RedisCacheConfiguration> initialCacheConfiguration;
// 支持动态创建缓存标识
private final boolean allowInFlightCacheCreation;


/**
 * 创建RedisCacheManager
 */
public static RedisCacheManager create(RedisConnectionFactory connectionFactory) {

     Assert.notNull(connectionFactory, "ConnectionFactory must not be null!");

     return new RedisCacheManager(new DefaultRedisCacheWriter(connectionFactory),
        RedisCacheConfiguration.defaultCacheConfig());
}

/**
 * 加载初始缓存
 */
protected Collection<RedisCache> loadCaches() {
    List<RedisCache> caches = new LinkedList<>();
    // 遍历初始缓存配置
    for (Map.Entry<String, RedisCacheConfiguration> entry :            initialCacheConfiguration.entrySet()) {
        caches.add(createRedisCache(entry.getKey(), entry.getValue()));
    }
    return caches;
}

/**
 * 动态创建缓存
 */
protected RedisCache getMissingCache(String name) {
    // 若支持动态创建就穿件新缓存,否则返回null
    return allowInFlightCacheCreation ? createRedisCache(name, defaultCacheConfig) : null;
}

/**
 * RedisCacheManager构造辅助类
 * 内部类
 */
public static class RedisCacheManagerBuilder {
    ...
    /**
     * 根据配置选项生成RedisCacheManager
     */
    public RedisCacheManager build() {
        Assert.state(cacheWriter != null,
            "CacheWriter must not be null! You can provide one via    'RedisCacheManagerBuilder#cacheWriter(RedisCacheWriter)'.");
        RedisCacheWriter theCacheWriter = cacheWriter;
        if (!statisticsCollector.equals(CacheStatisticsCollector.none())) {
            theCacheWriter = cacheWriter.withStatisticsCollector(statisticsCollector);
        }
        RedisCacheManager cm = new RedisCacheManager(theCacheWriter,    defaultCacheConfiguration, initialCaches, allowInFlightCacheCreation);
        // 设置事务支持
        cm.setTransactionAware(enableTransactions);
        return cm;
    }
}
 类似资料: