什么是缓存,为什么要用缓存
程序运行中,在内存保持一定时间不变的数据就是缓存。简单到写一个Map,里面放着一些key,value数据,就已经是个缓存了
所以缓存并不是什么高大上的技术,只是个概念,把要多次使用的东西存在一个变量里,时不时取出来使用,就达到了缓存的目的,缓存就是存放数据的容器
那为什么要用缓存呢,是因为要多次使用。一个程序总有一些数据时可预见被多次使用(预见的准不准就是常说的命中率)
比如一个复杂的计算结果,一次数据库访问取得的数据等耗时耗资源的数据就能放入缓存,目的就是为了节省开销,我们要用有限的资源(CPU,内存,带宽等等)尽量做最多的事情。
为什么要用SpringCache(缓存的演变过程)
缓存的思考
如果我们要设计一个缓存,最基本的功能是存和取:
1.能在缓存里存放数据
2.能在缓存里取出数据
可是这不够呀,比如以下的思考
1.取数据时判断,数据是否存在,如果不存在是不是要数据库取
2.如果是过期的内容是不是要更新
3.如果我有多个缓存,一个是我自己设计的HashMap缓存,一个是名声很大的redis,还有…,那需要个缓存管理器呀
为了让缓存更好用,更“智能”,越来越多的需求就会被提出来,而缓存就是这样一步步演变直到SpringCache横空出世,功能十分强大(说白了就是我们少写很多代码)
SpringCache的好处
SpringCache包含两个顶级接口,Cache(缓存)和CacheManager(缓存管理器),顾名思义,用CacheManager去管理一堆Cache。
最最关键的地方:抱紧了Spring的大腿,可以使用注解就能完成数据进入缓存!!
给大家举个例子,就知道多简单了
首先,Springboot中会自动加载一个CacheManager(它有默认的实现类),所以只要写好一个自定义的Cache即可(如果想用系统定义好的或者第三方如RedisCache也行,记得向Spring注册这个bean即可)
@Component
public class MyCache implements Cache {
/*
实现接口方法,一些关于数据set和get的方法
CacheManager是根据Cache的名字进行管理的
所以假设这个Cache名为MyCache
*/
}
然后在得出数据的方法上写上注释即可
@Cacheable(value = "MyCache",key = "#id")
public String getNavegationURLs(String id) {
//一个获取数据的方法
}
这样就会在调用这个方法时,会以id为key值,在名为MyCache的Cache容器中查找(注解中value就是缓存名字,不同名字指定使用不同的缓存)
如果没查到,则执行方法 getNavegationURLs,将返回值存入缓存
如果找到了,就直接将从缓存取值,直接返回,不用执行方法 getNavegationURLs
CacheManager工具类使用介绍
import lombok.AllArgsConstructor;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;
@Component
@AllArgsConstructor
public class CacheManagerUtil {
private CacheManager cacheManager;
/**
* 获取缓存信息
* @param cacheName 缓存名
* @param key 自定义key
* @param <T> 返回值
* @return
*/
@SuppressWarnings({"unchecked"})
public <T> T getCache(String cacheName,String key) {
Cache cache = cacheManager.getCache(cacheName);
if (cache == null) {
return null;
}
Cache.ValueWrapper valueWrapper = cache.get(key);
if (valueWrapper == null) {
return null;
}
return (T)valueWrapper.get();
}
/**
* 添加缓存信息
* @param cacheName
* @param key
* @param value
*/
public void putCache(String cacheName,String key, Object value) {
Cache cache = cacheManager.getCache(cacheName);
if (cache != null) {
cache.put(key, value);
}
}
/**
* 清理缓存
* @param cacheName
* @param key
*/
public void evictCache(String cacheName,String key) {
Cache cache = cacheManager.getCache(cacheName);
if (cache != null) {
cache.evict(key);
}
}
}