Java 缓存工具类(CacheUtils)

缓存是提高应用性能、减少数据库或外部系统访问频率的有效手段。在 Java 中,可以使用多种缓存实现方式,如本地内存缓存、分布式缓存(如 Redis、Memcached)、第三方库(如 Ehcache、Caffeine)。为了提供一个简单易用的缓存工具类,可以实现一个基于 Java Concurrent 包的本地缓存工具类 CacheUtils,支持基本的缓存操作,如存储、获取、删除缓存项,并支持过期时间设置。

一、CacheUtils 工具类设计

CacheUtils 工具类使用 Java 的 ConcurrentHashMap 作为缓存存储,并通过 ScheduledExecutorService 定期清理过期的缓存项。每个缓存项使用一个封装类 CacheEntry 来存储缓存的值及其过期时间。

依赖
 为了使用CacheUtils工具类,你需要以下依赖:
  1. Guava: Guava是Google的Java核心库,它提供了许多实用的工具类,包括缓存工具类。你可以在Maven中添加以下依赖来使用Guava:
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.1-jre</version>
</dependency>
  1. Caffeine: Caffeine是一个高性能的Java缓存库,它提供了更好的并发性能和内存使用效率。你可以在Maven中添加以下依赖来使用Caffeine:
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.9.0</version>
</dependency>

请注意,你可以选择使用Guava或Caffeine作为缓存库,或者根据自己的需求选择其他的缓存库。以上只是其中的两个常见选择。

使用CacheUtils工具类时,你应该使用其中一个缓存库的相关API来创建和管理缓存。CacheUtils只是对缓存库API的封装,使其更易于使用。为了使用CacheUtils工具类,你需要以下依赖:

  1. Guava: Guava是Google的Java核心库,它提供了许多实用的工具类,包括缓存工具类。你可以在Maven中添加以下依赖来使用Guava:
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.1-jre</version>
</dependency>
  1. Caffeine: Caffeine是一个高性能的Java缓存库,它提供了更好的并发性能和内存使用效率。你可以在Maven中添加以下依赖来使用Caffeine:
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.9.0</version>
</dependency>

请注意,你可以选择使用Guava或Caffeine作为缓存库,或者根据自己的需求选择其他的缓存库。以上只是其中的两个常见选择。

1. 工具类的基本结构

工具类通常包含静态方法,并且构造函数设为私有以防止实例化:

import java.util.Map;
import java.util.concurrent.*;

public class CacheUtils {

    // 缓存存储
    private static final Map<String, CacheEntry> cacheMap = new ConcurrentHashMap<>();

    // 定期清理过期缓存的线程池
    private static final ScheduledExecutorService cleaner = Executors.newSingleThreadScheduledExecutor();

    static {
        // 启动定期清理任务
        cleaner.scheduleAtFixedRate(CacheUtils::cleanUp, 10, 10, TimeUnit.SECONDS);
    }

    // 私有构造函数,防止实例化
    private CacheUtils() {
        throw new UnsupportedOperationException("Utility class");
    }

    // 其他实用方法将在下文详述
}
2. 缓存项封装类

每个缓存项使用 CacheEntry 类进行封装,包括缓存的值和过期时间:

// 缓存项封装类
class CacheEntry {
    private final Object value;
    private final long expiryTime;

    public CacheEntry(Object value, long expiryTime) {
        this.value = value;
        this.expiryTime = expiryTime;
    }

    public Object getValue() {
        return value;
    }

    public long getExpiryTime() {
        return expiryTime;
    }

    // 判断缓存项是否过期
    public boolean isExpired() {
        return System.currentTimeMillis() > expiryTime;
    }
}
3. 添加缓存

添加缓存项,并支持指定过期时间(单位:秒):

// 添加缓存项
public static void put(String key, Object value, long ttlInSeconds) {
    long expiryTime = System.currentTimeMillis() + ttlInSeconds * 1000;
    cacheMap.put(key, new CacheEntry(value, expiryTime));
}
4. 获取缓存

获取缓存项,如果缓存项已过期或不存在,则返回 null:

// 获取缓存项
public static Object get(String key) {
    CacheEntry entry = cacheMap.get(key);
    if (entry == null || entry.isExpired()) {
        cacheMap.remove(key); // 移除过期项
        return null;
    }
    return entry.getValue();
}
5. 删除缓存

删除指定的缓存项:

// 删除缓存项
public static void remove(String key) {
    cacheMap.remove(key);
}
6. 清理过期缓存

定期清理所有过期的缓存项:

// 清理过期的缓存项
private static void cleanUp() {
    for (String key : cacheMap.keySet()) {
        CacheEntry entry = cacheMap.get(key);
        if (entry != null && entry.isExpired()) {
            cacheMap.remove(key);
        }
    }
}

二、CacheUtils 工具类完整示例

以下是完整的 CacheUtils 工具类代码示例:

import java.util.Map;
import java.util.concurrent.*;

public class CacheUtils {

    // 缓存存储
    private static final Map<String, CacheEntry> cacheMap = new ConcurrentHashMap<>();

    // 定期清理过期缓存的线程池
    private static final ScheduledExecutorService cleaner = Executors.newSingleThreadScheduledExecutor();

    static {
        // 启动定期清理任务
        cleaner.scheduleAtFixedRate(CacheUtils::cleanUp, 10, 10, TimeUnit.SECONDS);
    }

    private CacheUtils() {
        throw new UnsupportedOperationException("Utility class");
    }

    // 添加缓存项
    public static void put(String key, Object value, long ttlInSeconds) {
        long expiryTime = System.currentTimeMillis() + ttlInSeconds * 1000;
        cacheMap.put(key, new CacheEntry(value, expiryTime));
    }

    // 获取缓存项
    public static Object get(String key) {
        CacheEntry entry = cacheMap.get(key);
        if (entry == null || entry.isExpired()) {
            cacheMap.remove(key); // 移除过期项
            return null;
        }
        return entry.getValue();
    }

    // 删除缓存项
    public static void remove(String key) {
        cacheMap.remove(key);
    }

    // 清理过期的缓存项
    private static void cleanUp() {
        for (String key : cacheMap.keySet()) {
            CacheEntry entry = cacheMap.get(key);
            if (entry != null && entry.isExpired()) {
                cacheMap.remove(key);
            }
        }
    }
}

// 缓存项封装类
class CacheEntry {
    private final Object value;
    private final long expiryTime;

    public CacheEntry(Object value, long expiryTime) {
        this.value = value;
        this.expiryTime = expiryTime;
    }

    public Object getValue() {
        return value;
    }

    public long getExpiryTime() {
        return expiryTime;
    }

    // 判断缓存项是否过期
    public boolean isExpired() {
        return System.currentTimeMillis() > expiryTime;
    }
}

三、使用示例

以下是 CacheUtils 工具类的使用示例:

public class TestCacheUtils {

    public static void main(String[] args) throws InterruptedException {
        // 添加缓存项,过期时间为 5 秒
        CacheUtils.put("key1", "value1", 5);
        System.out.println("Stored value: " + CacheUtils.get("key1"));

        // 等待 6 秒后,缓存项应已过期
        Thread.sleep(6000);
        System.out.println("Value after expiry: " + CacheUtils.get("key1"));

        // 添加新的缓存项
        CacheUtils.put("key2", "value2", 10);
        System.out.println("Stored value: " + CacheUtils.get("key2"));

        // 手动删除缓存项
        CacheUtils.remove("key2");
        System.out.println("Value after removal: " + CacheUtils.get("key2"));
    }
}

结论

CacheUtils 工具类为 Java 中的本地缓存操作提供了一个简单易用的接口,支持缓存的添加、获取、删除和定期清理过期缓存项。通过封装 ConcurrentHashMap 和定期清理任务,CacheUtils 可以在不依赖第三方库的情况下实现基本的缓存功能。在实际项目中,开发者可以根据需要扩展工具类的功能,例如添加缓存容量限制、统计缓存命中率等,以满足更复杂的缓存需求。

总结

CacheUtils是一个Java缓存工具类,用于简化在应用中使用缓存的操作。它提供了一组静态方法,用于存储、获取和删除缓存数据。

该工具类的主要功能包括:

  1. 存储缓存数据:通过put方法可以将数据存储到缓存中。可以指定一个键(key)来标识数据,并设置一个过期时间(expiration),以确保缓存数据在一定时间后自动失效。
  2. 获取缓存数据:通过get方法可以根据指定的键获取缓存数据。如果缓存数据已过期或不存在,则返回null。
  3. 删除缓存数据:通过remove方法可以根据指定的键从缓存中删除数据。如果指定的键不存在,则操作无效。
  4. 清空缓存数据:通过clear方法可以清空整个缓存,删除所有的缓存数据。

使用CacheUtils可以简化应用中对缓存的操作,提高代码的可读性和维护性。它可以用于各种场景,例如缓存数据库查询结果、缓存远程API的响应等。

需要注意的是,CacheUtils只是一个简化缓存操作的工具类,它并不实现具体的缓存功能。在使用CacheUtils之前,需要使用一个具体的缓存实现(如Ehcache、Redis等)来初始化缓存环境,并提供相应的缓存操作接口。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐