
本项目代码:https://gitee.com/yunjiao-source/tutorials4j/tree/master/framework
在微服务与高并发场景下,缓存是提升系统性能的关键手段。Spring Framework 提供了 Cache 和 CacheManager 抽象,但实际业务中往往需要融合本地缓存(如 Caffeine)和分布式缓存(如 Redis),形成多级缓存,同时还要支持异步加载、租户隔离等高级特性。本文介绍一款轻量级缓存框架的设计与实现,它基于 Spring Cache 抽象,通过工厂模式、模板方法模式,提供灵活、可扩展的缓存操作入口。
框架核心包含以下几个模块:
CacheManagerCreatorFactory):单例工厂,注册多种 CacheManagerCreator,根据类型获取对应的 Cache 实例。CacheTemplate 及其抽象实现):封装常见的缓存操作(get、put、delete、异步加载等),为业务层提供统一 API。CaffeineCacheTemplate、RedisCacheTemplate、MultiLevelCacheTemplate,分别对应本地、远程、多级缓存场景。CaptchaCacheTemplate 展示如何使用多级缓存实现验证码服务。整体类图关系如下:
CacheManagerCreatorFactory (单例)
│
├── 持有 List<CacheManagerCreator<?>>
│
└── 提供 getXxxCache(cacheName) : Cache
CacheTemplate<K,V> (接口)
│
└── AbstractCacheTemplate<K,V> (抽象类)
│
├── CaffeineCacheTemplate<K,V>
├── RedisCacheTemplate<K,V>
└── MultiLevelCacheTemplate<K,V>
│
└── CaptchaCacheTemplate (业务示例)CacheManagerCreatorFactory 是一个单例类,其职责是:根据缓存的“类型标识”获取对应的 CacheManagerCreator****,再由该创建器提供具体的** Cache** 实例。设计要点如下:
setCacheManagerCreators(List<...>) 注入所有创建器,支持 Spring 配置或手动调用。CacheManagerCreator 实现类都有一个全限定类名(如 DefaultConsts.CLASS_MULTI_LEVEL_CACHE_MANAGER_CREATOR),工厂根据类名通过反射或直接类比较来查找。getCaffeineCache 方法会先尝试获取带租户支持的创建器,再回退到普通创建器;getMultiLevelCache 中有一段重复代码(疑似遗留 bug,但不影响理解设计意图)。CacheManagerInstanceNotFoundException。这种设计将“哪些缓存管理器可用”与“如何使用它们”解耦,新增一种缓存类型(如 Hazelcast)只需增加对应的 CacheManagerCreator 实现并注册到工厂即可,无需修改业务模板代码。
CacheTemplate<K, V> 定义了以下核心方法:
方法 | 说明 |
|---|---|
| 存入键值对 |
| 原子性不存在则存入 |
| 获取值,可能返回 null |
| 获取或加载 |
| 删除 |
| 抽象方法:由子类定义如何生成默认值 |
| 默认方法:生成值并存入 |
| 异步获取/加载(底层需支持 Spring 5.2 后的 |
该接口既支持同步阻塞操作,也支持 CompletableFuture 异步编程,适应现代响应式业务需求。
AbstractCacheTemplate 实现了 CacheTemplate 的大多数方法,并实现了 SmartInitializingSingleton 接口。其关键设计是:
afterSingletonsInstantiated 回调)调用抽象方法 initCache(),由子类负责从工厂中获取实际的 Cache 对象。Cache 实例,减少重复代码。get(K key) 通过 getValueClass() 获取泛型类型,确保返回值的正确转换。类名 | initCache() 实现 | 适用场景 |
|---|---|---|
|
| 纯本地缓存,高性能,适合单机频繁读取、数据量可控的场景 |
|
| 纯分布式缓存,适合多实例共享数据、持久化需求 |
|
| 一级 Caffeine + 二级 Redis,兼顾性能与一致性 |
这三种模板均保持对工厂的松耦合,未来若需要更换缓存实现(例如从 Redis 切换到 Redisson),只需修改对应的 CacheManagerCreator 实现,业务层无需改动。
CaptchaCacheTemplate 是一个具体的业务示例,继承 MultiLevelCacheTemplate<String, String>,并实现了:
"captcha"String.classRandomStringUtils.secure().nextAlphanumeric(4) → 4 位随机串check(key, inputValue) 用于校验验证码通过该示例可以看出,业务开发者只需继承对应的缓存模板、指定泛型、实现少量抽象方法,就能获得完整的缓存能力,代码极其简洁。
以验证码服务为例,运行时流程如下:
CaptchaCacheTemplate 并实例化。afterSingletonsInstantiated() -> initCache() -> 通过 CacheManagerCreatorFactory 获取多级缓存实例(名称 captcha)。captchaCacheTemplate.create(phoneNumber) → 调用 valueGenerator 生成随机码 → 调用 multilevelCache.put(phoneNumber, code)。captchaCacheTemplate.get(phoneNumber) 获取已存储的验证码,与用户输入比对。整个过程中,开发者无需关心底层是本地缓存还是 Redis,也不需要编写任何 RedisTemplate 或 Caffeine 构造代码。
CacheManagerCreatorFactory 并不直接创建 CacheManager,而是委托给各个 CacheManagerCreator。这样每个缓存类型(Caffeine、Redis、多级)可以有自己的初始化逻辑(例如连接池、过期策略、序列化方式),符合开闭原则。
所有 CacheTemplate 实现类都复用 AbstractCacheTemplate 的通用操作,子类唯一需要关心的是如何初始化 cache 对象以及提供 valueGenerator。相比之下,传统做法每个业务类都要注入 CacheManager、根据名称获取 Cache、处理异常,代码冗余严重。
CacheTemplate 提供了 CompletableFuture<?> retrieve(K key) 方法,对应 Spring 5.2 引入的 Cache.retrieve(Object)。这允许业务层以非阻塞方式获取缓存,结合异步编程模型(如 WebFlux)可以大幅提升吞吐量。
通过实现 SmartInitializingSingleton,确保在 Spring 完成所有单例 Bean 的实例化、属性注入、初始化后,再获取底层 Cache。这避免了 Cache 未就绪就被使用的问题。
CacheManager Bean,并创建对应的 CacheManagerCreator 实现类(框架提供默认实现,本文未展示)。CacheManagerCreator 注入到 CacheManagerCreatorFactory.INSTANCE。@Service
public class UserCacheTemplate extends CaffeineCacheTemplate<Long, User> {
public UserCacheTemplate() {
super("users");
}
@Override
public Class<User> getValueClass() {
return User.class;
}
@Override
public User valueGenerator(Long userId) {
// 从数据库加载
return userDao.findById(userId);
}
}@Autowired
private UserCacheTemplate userCache;
public User getUser(Long id) {
return userCache.get(id); // 缓存命中则直接返回,未命中返回 null
}
public User getOrLoadUser(Long id) {
return userCache.get(id, () -> userDao.findById(id));
}getMultiLevelCache 方法中两次尝试获取同一个创建器,应删除冗余判断。getCacheManager(String className) 使用反射和类全名匹配,可增加缓存 Map<String, Class<?>> 避免重复 Class.forName。AbstractCacheTemplate 中 putIfAbsent 和 retrieve 等方法存在未检查的强制转换,可考虑引入 Cache.get(key, TypeReference) 方式提升类型安全。retrieve(K, Supplier<CF<V>>) 目前直接透传,实际可增加超时、降级等策略。本文介绍了一款基于 Spring Cache 抽象、采用工厂模式与模板方法模式构建的缓存框架。该框架通过 CacheManagerCreatorFactory 统一管理多种缓存类型(Caffeine、Redis、多级),通过 CacheTemplate 系列类为业务提供简洁、类型安全的操作接口。示例 CaptchaCacheTemplate 展示了如何仅用少量代码实现验证码缓存服务。整个框架具有良好的扩展性和可维护性,适合在需要灵活缓存策略的企业级项目中推广使用。
读最新文章,请关注我的微信公众号”杨运交”
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。