Spring Cache 集成 Caffeine实现项目缓存的示例

网友投稿 620 2022-11-12

Spring Cache 集成 Caffeine实现项目缓存的示例

Spring Cache 集成 Caffeine实现项目缓存的示例

目录一、前言二、缓存注解三、实战操作1、依赖引入2、yaml配置3、开启缓存4、模拟方法5、测试6、改造

一、前言

Spring Cache本身是Spring框架中一个缓存体系的抽象实现,本身不具备缓存能力,需要配合具体的缓存实现来完成,如Ehcache、Caffeine、Guava、Redis等。

二、缓存注解

@EnableCaching:开启缓存功能

@Cacheable:定义缓存,用于触发缓存

@CachePut:定义更新缓存,触发缓存更新

@CacheEvict:定义清楚缓存,触发缓存清除

@Caching:组合定义多种缓存功能

@CacheConfig:定义公共设置,位于class之上

三、实战操作

我选择使用目前-Caffeine来作为具体的缓存实现方式,下面是一个demo:

1、依赖引入

com.github.ben-manes.caffeine

caffeine

2.8.6

org.springframework.boot

spring-boot-starter-cache

2、yaml配置

spring:

cache:

cache-names: USER

caffeine:

spec: initialCapacity=50,maximumSize=500,expireAfterWrite=5s

type: caffeine

Caffeine配置说明

initialCapacity=[integer]: 初始的缓存空间大小

maximumSize=[long]: 缓存的最大条数

maximumWeight=[long]: 缓存的最大权重

expireAfterAccess=[duration]: 最后一次写入或访问后经过固定时间过期

expireAfterWrite=[duration]: 最后一次写入后经过固定时间过期

refreshAfterWrite=[duration]: 创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存

weakKeys: 打开key的弱引用

weakValues:打开value的弱引用

softValues:打开value的软引用

recordStats:开发统计功能

注意

expireAfterWrite和expireAfterAccess同事存在时,以expireAfterWrite为准。

maximumSize和maximumWeight不可以同时使用

weakValues和softValues不可以同时使用

3、开启缓存

4、模拟方法

service层

@Service

@Slf4j

public class CaffeineService {

public static Map map = new HashMap<>();

static {

map.put("1", "zhangsan");

map.put("2", "lisi");

map.put("3", "wangwu");

}

@Cacheable(value = "USER", key = "#id")

public String getUser(String id) {

log.info("getUser() run......");

return map.get(id);

}

@CachePut(value = "USER", key = "#id")

public String updateUser(String id, String name) {

log.info("updateUser() run......");

map.put(id, name);

return map.toString();

}

@CacheEvict(value = "USER", key = "#id")

public String delUser(String id) {

log.info("delUser() run......");

map.remove(id);

return map.toString();

}

}

controller层

@RestController

@RequestMapping("/cache")

@Slf4j

public class CaffeineController {

@Autowired

private CaffeineService caffeineService;

@GetMapping("/user/{id}")

public String getUser(@PathVariable String id) {

long start = System.currentTimeMillis();

String res = caffeineService.getUser(id);

long end = System.currentTimeMillis();

log.info("查询耗时:" + (end - start));

return res;

}

@GetMapping("/user/{id}/{name}")

public String updateUser(@PathVariable String id, @PathVariable String name) {

return caffeineService.updateUser(id, name);

}

@DeleteMapping("/user/{id}")

public String delUser(@PathVariable String id) {

return caffeineService.delUser(id);

}

}

5、测试

第一次查询:

第二次查询:

查询耗时明显小于第一次查询,因为第二次直接返回缓存,速度提升。

执行更新后再查询:

会使缓存失效。会重新执行查询方法查询

执行删除后再查询:

会使缓存失效。会重新执行查询方法查询

6、改造

上述通过yaml文件配置的方式不够灵活,无法实现多种缓存策略,所以现在一般使用javaconfig的形式进行配置。

下面是示例代码

@Configuration

public class CaffeineConfig {

@Bean

public CacheManager caffeineCacheManager() {

SimpleCacheManager simpleCacheManager = new SimpleCahttp://cheManager();

List caffeineCaches = new ArrayList<>();

for (CacheType cacheType : CacheType.values()) {

caffeineCaches.add(new CaffeineCache(cacheType.name(),

Caffeine.newBuilder()

.expireAfterWrite(cacheType.getExpires(), TimeUnit.SECONDS)

.build()));

}

simpleCacheManager.setCaches(caffeineCaches);

return simpleCacheManager;

}

}

publhttp://ic enum CacheType {

USER(5),

TENANT(20);

private int expireshttp://;

CacheType(int expires) {

this.expires = expires;

}

public int getExpires() {

return expires;

}

}

这样我们就能对USER设置5秒消防时间,对TENANT设置20秒消亡时间,在实http://际项目中这种方式更加的灵活。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:C++核心准则边译边学-P.4 理想情况下,程序应该静态类型安全
下一篇:C++核心准则边译边学-I.1: 使接口清晰明确
相关文章

 发表评论

暂时没有评论,来抢沙发吧~