专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java 本地缓存实战:基于 Hutool Time...

temp10 2025-08-06 22:56:08 java教程 12 ℃ 0 评论

在中小型系统中,某些数据我们希望缓存到本地内存中,提升访问效率,但又不想引入复杂的分布式缓存如 Redis。这时,Hutool 的 TimedCache 是个非常轻巧好用的方案。本文将基于实际项目封装一个通用的本地缓存工具类,并介绍其中的关键点和注意事项。

C 为什么使用 TimedCache ?

Hutool 是一套 Java 工具库,里面的 TimedCache 提供了带有效期的本地缓存机制:

Java 本地缓存实战:基于 Hutool Time...

  • 支持设置超时时间;
  • 支持按需刷新访问时间;
  • 支持定时清理;
  • 性能轻快,依赖少,适合单体服务或工具场景。

实战代码:封装一个通用缓存工具类

下面是我们封装的 HutoolCacheUtil ,功能包括: #技术分享

  • 缓存写入、读取(支持泛型)、删除
  • 支持是否刷新访问时间
  • 支持自定义缓存项超时时间
  • 支持定时清理过期数据(非常重要)
public class HutoolCacheUtil {

private static final TimedCache<String, Object> timedCache = CacheUtil.newTimedCache(1000 * 60 * 30);

static { timedCache.schedulePrune(1000 * 60 * 30); }

public static boolean containsKey(String key) { return timedCache.containsKey(key); }

public static Object get(String key) { return timedCache.get(key); }

@SuppressWarnings("unchecked") public static <T> T get(String key, boolean isUpdateLastAccess) { return (T) timedCache.get(key, isUpdateLastAccess); }

public static void put(String key, Object value) { _globalTimedCache.put(key, value); }

public static void put(String key, Object value, Integer timeout) { _globalTimedCache.put(key, value, timeout); }

public static void remove(String key) { _globalTimedCache.remove(key); }

public static void removeKeys(String keyword) { Set<String> keySet = _globalTimedCache.keySet(); keySet.forEach(k -> { if (k.contains(keyword)) { _globalTimedCache.remove(k); } }); } }

使用时你必须注意的坑

C 1 schedulePrune 是必须的

并且要注意 get(key) 方法是重置过期时间的,如果想避开这个机制,请调用 get("key1", false) 方法。

Hutool 的缓存虽然支持超时机制,但 不会自动清理已过期的项 ,默认只在访问时做清理。

如果你忘记设置 schedulePrune(...) ,过期缓存会常驻内存 ,导致内存占用越来越高。

_globalTimedCache.schedulePrune(1000 * 60 * 30);

2 泛型类型擦除问题

由于 Java 泛型擦除机制,缓存返回值需要强制类型转换,可能会出现警告:

List<MyDTO> list = (List<MyDTO>) HutoolCacheUtil.get("myListKey")

我们在工具类中加了:

@SuppressWarnings("unchecked")
public static <T> T get(String key, boolean isUpdateLastAccess)

@SuppressWarnings("unchecked") 这个注解告诉编译器“我知道你警告的是什么,这里我可以接受”,是安全的,只要你自己控制了 put 和 get 的类型一致。


3 不能用于分布式缓存!

这是 本地内存缓存 ,多个服务节点之间是互相不可见的。如果你有分布式部署场景,建议使用 Redis、Caffeine + Redis 等双缓存机制。


使用示例

// 缓存一个列表对象30分钟
List<MyDTO> list = queryFromDB()
HutoolCacheUtil.put("myList", list)

// 获取时自动重置过期时间(续命) List<MyDTO> cachedList = (List<MyDTO>) HutoolCacheUtil.get("myList")

// 获取但不续命(即不刷新 TTL) List<MyDTO> cachedList2 = HutoolCacheUtil.get("myList", false)

总结

| 功能 | 是否支持 | | ---

| 设置缓存超时 | | | 自动清理 | (需手动开启) | | 是否线程安全 | | | 泛型支持 | (通过抑制警告) | | 适合分布式使用 | | | 适合轻量场景 | |

Hutool 的 TimedCache 在轻量缓存场景下非常实用,适合本地缓存热点数据、接口返回、配置等内容。如果你想更灵活地封装,也可以按模块或业务类型区分不同缓存实例。

--- 建议 :将该工具类纳入你团队的基础工具库中,统一使用、统一清理、统一封装,避免代码重复和缓存混乱。

--- 有什么关于本地缓存实战的问题,欢迎评论区交流!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表