Redis应用缓存框架
1.Ehcache缓存框架
(1)Ehcache的核心对象
(2)单独使用Ehcache
(3)Spring整合Ehcache
(4)Spring Boot整合Ehcache
(5)实际工作中如何使用Ehcache
2.Guava Cache缓存框架
(1)Guava Cache具有如下功能
(2)Guava Cache的主要设计思想
(3)Cuava Cache的优势
(4)Cuava Cache核心原理
(6)Guava Cache的单独使用和与Spring集成使用
(7)Guava Cache的几个问题
3.自定义缓存
(1)缓存应该具备的功能
(2)基于LinkedHashMap来实现LRU淘汰策略
(3)基于LinkedList来实现LRU淘汰策略
(4)基于SoftReference实现缓存的内存敏感能力
1.Ehcache缓存框架
(1)Ehcache的核心对象
(2)单独使用Ehcache
(3)Spring整合Ehcache
(4)Spring Boot整合Ehcache
(5)实际工作中如何使用Ehcache
(1)Ehcache的核心对象
一.CacheManager
Cache的容器对象,并管理着Cache的生命周期。
二.Cache
一个Cache可以包含多个Element,并被CacheManager管理。
三.Element
需要缓存的元素,它维护着一个键值对,元素也可以设置有效期。
(2)单独使用Ehcache
一.配置好ehcache.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="false"
dynamicConfig="false">
<!-- ehcache.xsd的内容可以从网址"https://www.ehcache.org/ehcache.xsd"获取 -->
<!-- diskStore: 持久化到磁盘上时的存储位置 -->
<diskStore path="java.io.tmpdir/Tmp_Ehcache"/>
<!-- defaultCache: 默认的缓存策略,如果指定的缓存策略没有找到,那么就用这个默认的缓存策略 -->
<!-- eternal: 缓存对象是否一直存在,如果设置为true,那么timeout就没有效果,缓存就会一直存在,一般默认就是false -->
<!-- maxElementsInMemory: 缓存对象的最大个数 -->
<!-- overflowToDisk: 当内存中缓存对象数量达到maxElementsInMemory时,Ehcache将会把对象写到磁盘中;注意如果缓存的对象要写入到硬盘中,则该对象必须要实现Serializable接口 -->
<!-- diskPersistent: 在JVM崩溃时和重启之间,是否启用持久化的机制 -->
<!-- timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位秒),仅当eternal=false对象不是永久有效时使用,可选属性;默认值是0,也就是可闲置时间无穷大 -->
<!-- timeToLiveSeconds: 设置对象在失效前允许存活时间(单位秒),最大时间介于创建时间和失效时间之间,仅当eternal=false对象不是永久有效时使用;默认值是0,也就是对象存活时间无穷大 -->
<!-- memoryStoreEvictionPolicy: 当缓存对象数量达到maxElementsInMemory时,Ehcache将会根据指定的策略去清理内存;默认策略是LRU(最近最少使用),可以设置为FIFO(先进先出)或是LFU(较少使用) -->
<!-- maxElementsOnDisk: 硬盘最大缓存个数 -->
<!-- name: 缓存名称 -->
<defaultCache
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="300"
timeToLiveSeconds="0"
memoryStoreEvictionPolicy="LRU"
maxElementsOnDisk="100000"
/>
<!-- 手动指定的缓存策略 -->
<!-- 对不同的数据,缓存策略可以在这里配置多种 -->
<cache
name="cacheSpace"
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="300"
timeToLiveSeconds="0"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
二.在pom.xml文件引入Ehcache的依赖
<!-- 引入Ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
三.创建EhcacheDemo类
public class EhcacheDemo {
public static void main(String[] args) {
//1.获取CacheManager
CacheManager cacheManager = CacheManager.create("./src/main/resources/ehcache.xml");
//2.获取Cache实例,下面的demoCache在ehcache.xml中指定了
Cache demoCache = cacheManager.getCache("demoCache");
//3.存入元素
Element element = new Element("key1", "value1");
demoCache.put(element);
//4.取出元素
Element value = demoCache.get("key1");
System.out.println("value: " + value);
}
}
整体上看,Ehcache的使用是相对简单便捷的,提供了完整的各类API接口。需要注意,虽然Ehcache支持磁盘的持久化,但是由于存在两级缓存介质,在一级内存中的缓存如果没有主动刷入磁盘持久化,则在应用异常宕机时,依然会出现缓存数据丢失,为此可以根据需要将缓存刷到磁盘。将缓存条目刷到磁盘的操作可以通过cache.flush()方法来执行。需要注意:将对象写入磁盘前,要先将对象进行序列化。
(3)Spring整合Ehcache
Spring对缓存的支持类似于对事务的支持。首先使用注解标记方法,相当于定义了切点。然后使用AOP技术在这个方法的调用前、调用后获取方法的入参和返回值,从而实现缓存的逻辑。
一.@Cacheable注解
@Cacheable注解,表明所修饰的方法是可以缓存的。当第一次调用这个方法时,它的结果会被缓存下来,在缓存的有效时间内,以后访问这个方法都直接返回缓存结果,不再执行方法中的代码段。
@Cacheable注解注解可以用condition属性来设置条件。如果不满足条件,就不使用缓存能力,直接执行方法。
可以使用key属性来指定key的生成规则,@Cacheable支持如下几个参数。
参数一:value
缓存位置名称,不能为空。如果使用Ehcache,就是ehcache.xml中声明的cache的name,指明将值缓存到哪个Cache中。
参数二:key
默认情况下,缓存的key就是方法的参数,缓存的value就是方法的返回值。支持SpEL,如果要引用参数值使用井号加参数名,如:#userId。
一般来说,我们的更新操作只需刷新缓存中某一个值。所以定义缓存的key值的方式就很重要,最好是能够唯一。因为这样可以准确清除掉特定的缓存,而不会影响其他缓存值。
下面例子就使用了实体加冒号再加ID组合成键的名称,如"user:1000"。当有多个参数时,默认就使用多个参数来做key。如果只需要其中一个参数做key,则可以在@Cacheable注解中,通过key属性来指定key,如下代码就表示只使用ID作为缓存的key。如果对key有复杂的要求,可自定义keyGenerator,即实现keyGenerator。然后在使用的地方,利用注解中的keyGenerator来指定key生成策略。
参数三:condition
触发条件,只有满足条件的情况才会加入缓存。默认为空,即表示全部都加入缓存,支持SpEL。
二.@CachePut注解
@CachePut不仅会缓存方法的结果,还会执行方法的代码段。@CachePut支持的属性和用法都与@Cacheable一致。
三.@CacheEvict注解
与@Cacheable功能相反,@CacheEvict表明所修饰的方法是用来删除失效或无用的缓存数据。
@CacheEvict支持如下几个参数:
参数一:value,缓存位置名称,不能为空,同上
参数二:key,缓存的key,默认为空,同上
参数三:condition,触发条件,只有满足条件才清除缓存,支持SpEL
参数四:allEntries,true表示清除value中的全部缓存,默认为false
步骤一:在pom.xml引入相关依赖
<properties>
<maven.complier.source>8</maven.complier.source>
<maven.complier.target>8</maven.complier.target>
<junit.version>4.10</junit.version>
<spring.version>4.2.3.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- springframework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 引入Ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
</dependencies>
步骤二:在ehcache.xml添加一个缓存
<cache
name="userCache"
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LRU"
/>
步骤三:添加Spring配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-pac