SpringBoot缓存Caffeine使⽤解析⽬录
Redis和Caffeine的区别
相同点
不同点
联系
Spring Boot 缓存 Caffeine使⽤
1.需要添加的依赖
2.配置
3.使⽤Caffeine缓存
Caffeine其他常⽤注解
⼿动添加、获取、删除缓存
1.从缓存中获取数据
2.向缓存中添加数据
3.删除缓存中的数据
Redis和Caffeine的区别
相同点
两个都是缓存的⽅式
不同点
redis是分布式缓存,通过⽹络将数据存储到redis服务器内存⾥
caffeine是将数据存储在本地应⽤⾥
caffeine和redis相⽐,没有了⽹络IO上的消耗
联系
⼀般将两者结合起来,形成⼀⼆级缓存。
使⽤流程⼤致如下:
先去⼀级缓存中查数据(caffeine-本地应⽤内),
如果没有的话,去⼆级缓存中查数据(redis-内存),
再没有,再去数据库中查数据(数据库-磁盘)
Spring Boot 缓存 Caffeine使⽤
1.需要添加的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.6</version>
</dependency>
2.配置
在SpringBoot中配置Caffeine,控制缓存⾏为(例如过期时间,缓存⼤⼩限制等)
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import t.annotation.Bean;
import t.annotation.Configuration;
import urrent.TimeUnit;
@Configuration
@EnableCaching //开启缓存
public class CaffeinConfig {
@Bean
//配置Caffeine缓存⾏为(例如到期,缓存⼤⼩限制等)
public Caffeine caffeineConfig() {
Caffeine caffeine = wBuilder()
.expireAfterWrite(60, TimeUnit.MINUTES)
.
maximumSize(1000);
return caffeine;
}
@Bean
public CacheManager cacheManager(Caffeine caffeine) {
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCaffeine(caffeine);
return caffeineCacheManager;
}
}
Caffeine配置说明:
initialCapacity=[integer]:初始的缓存空间⼤⼩
maximumSize=[long]:缓存的最⼤条数
maximumWeight=[long]:缓存的最⼤权重
expireAfterAccess=[duration]:最后⼀次写⼊或访问后经过固定时间过期
expireAfterWrite=[duration]:最后⼀次写⼊后经过固定时间过期
refreshAfterWrite=[duration]:创建缓存或者最近⼀次更新缓存后经过固定的时间间隔,刷新缓存
recordStats:开发统计功能
注意:
expireAfterWrite和expireAfterAccess同时存在时,以expireAfterWrite为准。
maximumSize和maximumWeight不可以同时使⽤
3.使⽤Caffeine缓存
⽰例1:
使⽤ @Cacheable(cacheNames = “xxx”) 或 @Cacheable(value = “xxx”) 注解在⽅法上。
@Cacheable(value = "caffeinSet_Value")
public String caffeinSetValue(Integer number) {
String str = number % 2 == 0 ? number + "是偶数" : number + "是奇数";
return str;
}
说明:每次执⾏⽅法 caffeinSetValue 时,会先去 caffeinSet_Value 缓存⾥根据传⼊的 number 查有没有匹配的缓存,有则直接返回结果;没有则执⾏⽅法,执⾏完后将结果加⼊缓存⾥,下次如果匹配直接返回。
⽰例2:
当有多个参数时,@Cacheable 注解⾥可以使⽤ key 来选择参数进⾏判断缓存是否存在。可以使⽤ con
dition 来进⾏条件筛选,只有满⾜条件的才会加⼊缓存。
/**
* number为偶数时才会缓存,缓存的key是传⼊的number值
*/
@Cacheable(value = "caffeinSet_Value", key = "#number", condition = "#number%2==0")
public String caffeinSetValue(Integer number,String st) {
String str = number % 2 == 0 ? number + "是偶数" : number + "是奇数";
return str+st;
}
说明:假如传⼊的参数 number 是2,⾸先判断 caffeinSet_Value 缓存⾥有没有 key 是2的,有则直接回结果。没有则执⾏⽅法,因为满⾜ condition 的条件则最后将结果加⼊缓存。
假如传⼊的参数 number 是奇数,则每次都会执⾏⽅法,因为不满⾜ condition ,不会被加⼊缓存。
⽰例3:
@Cacheable(value = "caffeinSet_Value", key = "#student.name", condition = "#student.age>10")
public Student caffeinSetValue(Student student,Integer number) {
springframework和springbootSystem.out.println(11111);
return student;
}
说明:根据student对象⾥的name去caffeinSetValue缓存⾥查。只有student对象⾥的age⼤于10的时候才会缓存结果。
注意:
⼀个⽅法A调同⼀个类⾥的另⼀个有缓存注解的⽅法B,这样是不⾛缓存的。
例如在同⼀个CaffeinConsumer 类⾥⾯ invalidCache 调⽤ caffeinSetValue,是不⾛缓存的,缓存是不⽣效的;
@Service
public class CaffeinConsumer {
public String invalidCache(Integer number,String st) {
String str = caffeinSetValue(number,st);
return str;
}
/**
* number为偶数时才会缓存,缓存的key是传⼊的number值
*/
@Cacheable(value = "caffeinSet_Value", key = "#number", condition = "#number%2==0")
public String caffeinSetValue(Integer number,String st) {
String str = number % 2 == 0 ? number + "是偶数" : number + "是奇数";
return str+st;
}
}
解决⽅案:
1.不使⽤注解的⽅式,直接取 Ehcache 的 CacheManger 对象,把需要缓存的数据放到⾥⾯,类似于使⽤ Map,缓存的逻辑⾃⼰控制;或者可以使⽤redis的缓存⽅式去添加缓存;
2.把⽅法A和⽅法B放到两个不同的类⾥⾯,例如:如果两个⽅法都在同⼀个service接⼝⾥,把⽅法B放到另⼀个service⾥⾯,这样在A⽅法⾥调B⽅法,就可以使⽤B⽅法的缓存。
Caffeine其他常⽤注解
1.@CachePut:
被@CachePut标注的⽅法在执⾏前不会去检查缓存中是否存在之前执⾏过的结果,⽽是每次都会执⾏该
⽅法,并将执⾏结果以键值对的形式存⼊指定的缓存中。
2.@CacheEvict:
@CacheEvict是⽤来标注在需要清除缓存元素的⽅法或类上的。当标记在⼀个类上时表⽰其中所有的⽅法的执⾏都会触发缓存的清除操作。
@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的语义与@Cacheable对应的属性类似。
即value表⽰清除操作是发⽣在哪些Cache上的(对应Cache的名称);key表⽰需要清除的是哪个key,如未指定则会使⽤默认策略⽣成的key;condition表⽰清除操作发⽣的条件。如果要清除所有缓存可使⽤属性 allEntries=true
⼿动添加、获取、删除缓存
上⾯的⼀些⽰例通过注解来进⾏缓存操作,有时候我们需要在⼀些⽅法⾥对缓存进⾏操作增删改查:
1.从缓存中获取数据
假设上⾯⽰例2中向名为 “caffeinSet_Value”的缓存⾥加⼊的键是8,值是"8是偶数!!"。
下⾯⼿动获取此缓存:
@Autowired
CacheManager cacheManager;
public String caffeinGetValue() {
Cache cache = Cache("caffeinSet_Value");
//获取缓存名称。name为caffeinSetValue
String name = Name();
//获取caffeinSetValue缓存⾥建是8的缓存
Cache.ValueWrapper value = (8);
String str ="";
if (null != value) {
/
/获取值,8是偶数!!
str = String.());
}
return str;
}
2.向缓存中添加数据
@Autowired
CacheManager cacheManager;
public String caffeinPutValue() {
Cache cache = Cache("caffeinSet_Value");
//获取缓存名称。name为caffeinSetValue
String name = Name();
/*
//向缓存中put数据。如果不存在key是20的才会加⼊
cache.putIfAbsent(number, "添加测试");
*/
//向缓存中put数据。如果存在key是20的会覆盖原来的数据
cache.put(20,"20是偶数!!");
return "成功";
}
3.删除缓存中的数据
删除caffeinSet_Value缓存中的某条缓存:
@Autowired
CacheManager cacheManager;
public String caffeinDeleteValue() {
Cache cache = Cache("caffeinSet_Value");
//获取缓存名称。name为caffeinSetValue
String name = Name();
//只有20这条数据存在才会删除
boolean bo = cache.evictIfPresent(20);
return String.valueOf(bo);
}
删除caffeinSet_Value缓存中的所有缓存:
@Autowired
CacheManager cacheManager;
public String caffeinDeleteAllValue() {
Cache cache = Cache("caffeinSet_Value");
//获取缓存名称。name为caffeinSetValue
String name = Name();
//删除caffeinSet_Value中的所有缓存
boolean bo = cache.invalidate();
return String.valueOf(bo);
}
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。