Guava Cache缓存:
- github地址:CachesExplained · google/guava Wiki · GitHub
- 全内存的本地缓存实现
- 高性能且功能丰富
- 线程安全,操作简单 (底层实现机制类似ConcurrentMap)
spring使用 Guava Cache缓存:
- 添加依赖
<!--guava依赖包--> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>19.0</version> </dependency>
- 封装api
private Cache<String,Object> tenMinuteCache = CacheBuilder.newBuilder()
//设置缓存初始大小,应该合理设置,后续会扩容
.initialCapacity(10)
//最大值
.maximumSize(100)
//并发数设置
.concurrencyLevel(5)
//缓存过期时间,写入后10分钟过期
.expireAfterWrite(600,TimeUnit.SECONDS)
//统计缓存命中率
.recordStats()
.build();
public Cache<String, Object> getTenMinuteCache() {
return tenMinuteCache;
}
public void setTenMinuteCache(Cache<String, Object> tenMinuteCache) {
this.tenMinuteCache = tenMinuteCache;
}
- 调用 存取缓存 (将轮播图列表放入缓存)
cache.get("key",()->{
查询数据;
返回数据;
}); 查询数据放入缓存,并且返回; 如果缓存里有数据 就直接返回
if(cacheObj instanceof List){ 判断类型
强转;
返回;
}
try{
Object cacheObj = baseCache.getTenMinuteCache().get(CacheKeyManager.INDEX_BANNER_KEY, ()->{
//查询数据库轮播图列表
List<VideoBanner> bannerList = videoMapper.listVideoBanner();
return bannerList;
});
if(cacheObj instanceof List){ //判断该对象是否是List类 是 强转
List<VideoBanner> bannerList = (List<VideoBanner>)cacheObj;
return bannerList;
}
}catch (Exception e){
e.printStackTrace();
}
return null;
spring项目中使用 Ehchach 缓存
- 全内存的本地缓存实现
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>
2.10
.
2
</version>
<type>pom</type>
</dependency>
- 使用 (Element、Cache、cacheManager是Ehcacle最重要的API)
创建配置文件:
-
<?xml version="1.0" encoding="UTF-8"?> <ehcache name="es"> <!-- 磁盘缓存位置 --> <diskStore path="java.io.tmpdir"/> <!-- 默认缓存 --> <defaultCache maxElementsInMemory="100" eternal="false" timeToIdleSeconds="172800" timeToLiveSeconds="172800" overflowToDisk="true" maxElementsOnDisk="10000" memoryStoreEvictionPolicy="LRU" > <!--<persistence strategy="localTempSwap"/>--> </defaultCache> <!-- AbsSendCache缓存 --> <cache name="AbsSendCache" maxElementsInMemory="1" eternal="false" timeToIdleSeconds="172800" timeToLiveSeconds="172800" diskPersistent="true" overflowToDisk="true" diskSpoolBufferSizeMB="10" maxElementsOnDisk="10000" memoryStoreEvictionPolicy="LRU" /> </ehcache>
ehcache.xml配置参数说明:
- name:缓存名称。
- maxElementsInMemory:缓存最大个数。
- eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
- timeToIdleSeconds:置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
- timeToLiveSeconds:缓存数据的生存时间(TTL),也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
- maxEntriesLocalDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
- overflowToDisk:内存不足时,是否启用磁盘缓存。
- diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
- maxElementsOnDisk:硬盘最大缓存个数。
- diskPersistent:是否在VM重启时存储硬盘的缓存数据。默认值是false。
- diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
- memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
- clearOnFlush:内存数量最大时是否清除。
添加spring配置类:
@Configuration
public class ehcacheConfig {
/**
* shiro缓存管理器;
* 需要注入对应的其它的实体类中:
* 安全管理器:securityManager
*
* @return
*/
@Bean(name="ehCacheManagerAbs")
public EhCacheManager ehCacheManager() {
EhCacheManager cacheManager = new EhCacheManager();
cacheManager.setCacheManagerConfigFile("classpath:ehcache/ehcache.xml");
// resources下的 ehcache.xml路径
return cacheManager;
}
}
存取数据:
//存
Cache cache = ehCacheManager.getCacheManager().getCache("AbsSendCache");
Element downElement = new Element(key, Object);
cache.put(downElement);
cache.flush(); //刷新缓存
//取
Object object = cache.get(key);
//删
cache.remove("key1");
//关闭缓存管理器
ehCacheManager.shutdown();
注释;想让数据自动持久化
想利用spring 的注解,不想手动shutdown ,因此web.xml 配置listener 监听,在销毁的时候进行shutdown,这里利用ehcache 的监听.
<!-- ehcache 磁盘缓存 监控,持久化恢复 -->
<listener>
<listener-class>net.sf.ehcache.constructs.web.ShutdownListener</listener-class>
</listener>
直接杀死线程,肯定监听不到。
需要加监听器 net.sf.ehcache.constructs.web.ShutdownListener.
就是程序停止的时候 自动关闭缓存管理器