GuavaCache中LoadingCache的使用

背景

LoadingCache是GuavaCache构建缓存实体的方法,是一个支持多线程并发读写、高性能、通用的in-heap(堆)本地缓存。
支持key不存在时按照给定的CacheLoader 的loader方法进行loading。如果有多个线程同时get一个不存在的key,那么会有一个线程负责load,其他线程阻塞wait等待。

CacheBuilder方法参数

  • maximumSize(): 最大缓存上限,快达到上限或达到上限,处理了时间最长没被访问过的对象或者根据配置的被释放的对象
  • expireAfterAccess():设置时间对象没有被读/写访问则对象从内存中删除,回收顺序和基于大小回收一样
  • expireAfterWrite(): 设置时间对象没有被写访问则对象从内存中删除
  • refreshAfterWrite():为缓存增加自动定时刷新功能。缓存项只有在被检索时才会真正刷新,即只有刷新间隔时间到了再去get(key)才会重新去执行Loading,否则就算刷新间隔时间到了也不会执行loading操作。

CacheLoader

实现自动加载缓存。可以在其中自定义load方法和reload方法,根据需求加载缓存和刷新缓存。

Cache常用方法

  • get(key): 有值则返回缓存值,没有则执行load方法加载缓存。
  • put(key, value): 显式地向缓存中插入值,会直接覆盖掉已有键之前映射的值。
  • invalidate(key): 显式地清除个别缓存项。
  • invalidateAll(keys): 批量清除缓存项。
  • invalidateAll(): 清除所有缓存项。
  • refresh(key): (异步)主动刷新对应缓存值 。在刷新操作进行时,缓存仍然可以向其他线程返回旧值。

示例代码

基础代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// 实体类
@TableName("mid_user_info")
@Data
@Accessors(chain = true)
public class UserInfoPO {
 
    /**
     * 主键ID
     */
    @TableId
    private Long id;
 
    /**
     * 用户名
     */
    private String username;
 
    /**
     * 邮箱
     */
    private String email;
 
    /**
     * 电话
     */
    private String phone;
 
    /**
     * 创建时间
     */
    private Date createTime;
 
    /**
     * 更新时间
     */
    private Date updateTime;
 
    public UserInfoPO() {
    }
 
    public UserInfoPO(String username, String email, String phone) {
        this.username = username;
        this.email = email;
        this.phone = phone;
    }
}
 
// Service 实体类
@Service
@Slf4j
public class UserInfoService extends BaseService<UserInfoMapper, UserInfoPO> {
 
    /**
     * 根据参数获取实体
     */
    public UserInfoPO getEntityByParams(String username) {
        Wrapper<UserInfoPO> wrapper = new EntityWrapper<>();
        wrapper.eq("username", username);
        return this.selectOne(wrapper);
    }
 
    public List<UserInfoPO> selectAll() {
        Wrapper<UserInfoPO> wrapper = new EntityWrapper<>();
        return this.selectList(wrapper);
    }
 
}
 
// Mapper实体类
@Mapper
@Component
public interface UserInfoMapper extends BaseMapper<UserInfoPO> {
 
}

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@Slf4j
@Component
public class UserCacheService {
 
    @Autowired
    UserInfoService userInfoService;
 
    /**
     * guava cache 缓存实体
     */
    LoadingCache<String, UserInfoPO> cache = CacheBuilder.newBuilder()
            // 缓存刷新时间【30分钟过期】
            .expireAfterAccess(30, TimeUnit.MINUTES)
            // 设置缓存最大个数
            .maximumSize(500)
            .build(new CacheLoader<String, UserInfoPO>() {
                @Override
                // 当本地缓存命没有中时,调用load方法获取结果并将结果缓存
                public UserInfoPO load(String appKey) {
                    log.info("获取用户详情,用户名:{}", appKey);
                    return userInfoService.getEntityByParams(appKey);
                }
            });
 
    /**
     * 对外暴露的方法
     * 从缓存中取entry,没取到就走数据库
     */
    public UserInfoPO getUserInfo(String username) throws ExecutionException {
        log.info("进入 cache 获取用户信息,用户名:{}", username);
        return cache.get(username);
    }
 
    @PostConstruct
    public void initCache() {
        log.info("初始化员工缓存数据开始!");
        //读取所有记录
        List<UserInfoPO> userInfoList = userInfoService.selectAll();
        if (CollectionUtils.isEmpty(userInfoList)) {
            return;
        }
        for (UserInfoPO userInfo : userInfoList) {
            try {
                this.getUserInfo(userInfo.getUsername());
            } catch (Exception e) {
                log.error("初始化员工缓存数据异常:", e);
            }
        }
        log.info("初始化员工缓存数据结束!");
    }
}

参考

posted @   菜鸟的奋斗之路  阅读(1123)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示