简单使用
引入依赖
<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;
}