SpringBoot中设置超时30分钟自动删除元素的List和Map

时间:2024-11-24 07:07:50

简介

在 Spring Boot 中,你可以使用多种方法来实现自动删除超时元素的 List 或 Map。以下是两种常见的方式:

  • 如果你需要简单的功能并且不介意引入外部依赖,可以选择 Guava Cache。
  • 如果你想要更灵活的控制,使用 Spring 的调度功能也是一个不错的选择。

1. 使用 Scheduled Task

你可以使用 Spring 的 @Scheduled 注解来定期清理过期的元素。

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@EnableScheduling
public class CacheManager {

    //by https://zhengkai.blog.****.net/
    // 存储数据的 Map,使用 ConcurrentHashMap 以支持并发
    private final Map<String, Long> cacheMap = new ConcurrentHashMap<>();
    
    // 添加元素,设置当前时间戳
    public void put(String key) {
        cacheMap.put(key, System.currentTimeMillis());
    }

    // 定期清理超时元素
    @Scheduled(fixedRate = 60000) // 每分钟执行一次
    public void cleanUp() {
        long currentTime = System.currentTimeMillis();
        long timeout = 30 * 60 * 1000; // 30 分钟超时

        Iterator<Map.Entry<String, Long>> iterator = cacheMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Long> entry = iterator.next();
            if (currentTime - entry.getValue() > timeout) {
                iterator.remove(); // 删除超时元素
            }
        }
    }

    // 获取元素
    public Boolean get(String key) {
        return cacheMap.containsKey(key);
    }
}

在上面的代码中,我们创建了一个 CacheManager 类,它使用 ConcurrentHashMap 来存储元素及其添加时间。@Scheduled 注解用于定义定期清理超时元素的任务。定期任务每分钟执行一次,检查并删除 30 分钟之前添加的元素。

2. 使用 Guava Cache

如果你希望更简单地管理缓存,可以使用 Guava 的 Cache。它提供了过期策略的支持。

示例代码

首先,确保在 pom.xml 中添加 Guava 依赖:

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>33.3.1-jre</version>
</dependency>

然后,使用 Guava Cache:

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

@Component
public class CacheManager {

    private Cache<String, String> cache;

    @PostConstruct
    public void init() {
        // 创建一个支持过期的缓存,30分钟后过期。 by https://zhengkai.blog.****.net/
        cache = CacheBuilder.newBuilder()
                .expireAfterWrite(30, TimeUnit.MINUTES)
                .build();
    }

    // 添加元素
    public void put(String key, String value) {
        cache.put(key, value);
    }

    // 获取元素
    public String get(String key) {
        return cache.getIfPresent(key);
    }
}

在这个例子中,我们使用 Guava 的 CacheBuilder 创建了一个具有 30 分钟自动过期策略的缓存。使用 put 方法可以添加元素,而使用 getIfPresent 方法可以获取当前元素。