跳过正文
  1. 全部文章/

Kotlin内本地缓存拓展方法

目录

写业务的时候经常需要缓存一些数据,比如从 Redis 拿回来的列表,没必要每次都去请求。 但又不想引入一个重量级的缓存框架,就自己撸了个基于 ConcurrentHashMap 的本地缓存扩展方法。

支持过期时间,线程安全,用起来一行搞定。

实现代码
#

 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

import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit

data class CacheItem<T>(val value: T, val expireAt: Long)
val localCache = ConcurrentHashMap<String, CacheItem<Any>>()

/**
 * 一个通用的本地缓存获取数据的扩展方法。
 * @param key 缓存键。
 * @param expireAfterMillis 缓存项的有效期(毫秒),默认值为1小时。
 * @param fetcher 在缓存未命中或数据过期时用于获取新数据的lambda表达式。
 * @return 缓存或新获取的数据。
 */
inline fun <reified T> getFromCacheOrFetch(
    key: String,
    expireAfterMillis: Long = TimeUnit.HOURS.toMillis(1), // 设置默认的过期时间为1小时
    fetcher: () -> T?
): T? {
    val now = System.currentTimeMillis()
    val cacheItem = localCache[key]

    if (cacheItem != null && now < cacheItem.expireAt && cacheItem.value is T) {
        return cacheItem.value as T
    } else {
        val newValue = fetcher()
        if (newValue != null) {
            localCache[key] = CacheItem(newValue as Any, now + expireAfterMillis)
        }
        return newValue
    }
}

使用方法
#

调用的时候传个 key 和获取数据的 lambda 就行,缓存命中直接返回,过期了自动重新拉取。

1
2
3
4
5
6
7
8
    fun getRandomDeviceProfile(expireAfterMillis: Long = TimeUnit.MINUTES.toMillis(10)): String? {
        val key="XHS:DeviceProfileList"
        val randomResult=getFromCacheOrFetch(key, expireAfterMillis) {
            // 这里是你的数据获取逻辑
            getAllListValues(key)
        }
        return randomResult?.randomOne()
    }

相关文章