springboot缓存

首页

简单使用

引入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

启动类加注解@EnableCaching

@SpringBootApplication
@EnableAsync
@EnableCaching
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

在需要缓存的方法上加注解@Cacheable

    @Cacheable(cacheNames = {"user"})
    public User getById(int id) {
        System.out.println("enter userService getById");
        return userMapper.getById(id);
    }

调用getById方法时,如果传参相同,后面的调用就会直接从缓存中获取,而不会调用userMapper

自实现

缓存的基本功能,首先要有一个地方用于内容存储,可以选择用map,实现缓存的基本增删改查功能。其次缓存有过期时间,可以选择用定时任务,定时去掉map中过期的内容。

内容存储

    public static Map<String, Object> cacheMap = new ConcurrentHashMap<>();

    public void add(String key, Object value) {
        cacheMap.put(key, value);
    }

    public void remove(String key) {
        cacheMap.remove(key);
    }

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

带过期时间新增

新增一个存储对象。包含值和过期时间

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CacheObj {
    private Object object;
    private Long time;
}

往map中存储的时候,就存储上面定义的对象

public static Map<String, CacheObj> cacheMap = new ConcurrentHashMap<>();
    public void set(String key, Object value, Long time) {
        CacheObj cacheObj = new CacheObj(value, System.currentTimeMillis()+time);
        cacheMap.put(key, cacheObj);
    }

定时任务处理

定时任务可以使用java自带的TimerTask,首先先建一个删除任务

    class DeleteTask extends TimerTask {
        @Override
        public void run() {
            for (Map.Entry<String, CacheObj> entry : cacheMap.entrySet()) {
                Long time = entry.getValue().getTime();
                if (time < System.currentTimeMillis()) {
                    cacheMap.remove(entry.getKey());
                }
            }
        }
    }

新建定时任务,每秒中执行一次

    private void deleteTask(){
        Timer timer = new Timer();
        timer.schedule(new DeleteTask(),0,1000);
    }

在类创建时启动定时任务

    public CacheManager(){
        deleteTask();
    }

完整的类

package cn.wfc.util.cache;

import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author wfc
 * @CREATE 2022/5/13 9:09
 */
public class CacheManager {

    public static Map<String, CacheObj> cacheMap = new ConcurrentHashMap<>();

    public void add(String key, CacheObj value) {
        cacheMap.put(key, value);
    }

    public void remove(String key) {
        cacheMap.remove(key);
    }

    public CacheObj get(String key) {
        return cacheMap.get(key);
    }

    public void set(String key, Object value, Long time) {
        CacheObj cacheObj = new CacheObj(value, System.currentTimeMillis()+time);
        cacheMap.put(key, cacheObj);
    }

    public CacheManager(){
        deleteTask();
    }

    public static void main(String[] args) {
        CacheManager cacheManager = new CacheManager();
    }
    private void deleteTask(){
        Timer timer = new Timer();
        timer.schedule(new DeleteTask(),0,1000);
    }

    class DeleteTask extends TimerTask {
        @Override
        public void run() {
            for (Map.Entry<String, CacheObj> entry : cacheMap.entrySet()) {
                Long time = entry.getValue().getTime();
                if (time < System.currentTimeMillis()) {
                    cacheMap.remove(entry.getKey());
                }
            }
        }
    }
}

package cn.wfc.util.cache;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Author wfc
 * @CREATE 2022/5/13 9:37
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CacheObj {
    private Object object;
    private Long time;
}

测试

    public static void main(String[] args) throws InterruptedException {
        CacheManager cache = new CacheManager();
        cache.set("111","yes",5000L);
        System.out.println(cache.get("111"));
        TimeUnit.SECONDS.sleep(6);
        System.out.println(cache.get("111"));
        System.out.println("end");
    }

测试中第一次可以获取,后面就不能获取

获取时判断是否过期

删除可以晚点做,用于清理空间。但是获取的时候,需要实时判断是否过期

    public CacheObj get(String key) {
        CacheObj cacheObj = cacheMap.get(key);
        if (cacheObj == null) {
            return null;
        }
        if (cacheObj.getTime() < System.currentTimeMillis()) {
            return null;
        }
        return cacheObj;
    }

版权声明:本文为weixin_38400347原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。