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、依赖引入

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.8.6</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

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<String, String> 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 SimpleCacheManager();
        List<CaffeineCache> 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;
    }
}
public enum CacheType {

    USER(5),
    TENANT(20);

    private int expires;

    CacheType(int expires) {
        this.expires = expires;
    }

    public int getExpires() {
        return expires;
    }

}

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

到此这篇关于Spring Cache 集成 Caffeine实现项目缓存的示例的文章就介绍到这了,更多相关Spring Cache Caffeine缓存内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot+SpringCache实现两级缓存(Redis+Caffeine)

    1. 缓存.两级缓存 1.1 内容说明 Spring cache:主要包含spring cache定义的接口方法说明和注解中的属性说明 springboot+spring cache:rediscache实现中的缺陷 caffeine简介 spring boot+spring cache实现两级缓存 使用缓存时的流程图 1.2 Sping Cache spring cache是spring-context包中提供的基于注解方式使用的缓存组件,定义了一些标准接口,通过实现这些接口,就可以通过在方法

  • spring boot+spring cache实现两级缓存(redis+caffeine)

    spring boot中集成了spring cache,并有多种缓存方式的实现,如:Redis.Caffeine.JCache.EhCache等等.但如果只用一种缓存,要么会有较大的网络消耗(如Redis),要么就是内存占用太大(如Caffeine这种应用内存缓存).在很多场景下,可以结合起来实现一.二级缓存的方式,能够很大程度提高应用的处理效率. 内容说明: 缓存.两级缓存 spring cache:主要包含spring cache定义的接口方法说明和注解中的属性说明 spring boot

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

    目录 一.前言 二.缓存注解 三.实战操作 1.依赖引入 2.yaml配置 3.开启缓存 4.模拟方法 5.测试 6.改造 一.前言 Spring Cache本身是Spring框架中一个缓存体系的抽象实现,本身不具备缓存能力,需要配合具体的缓存实现来完成,如Ehcache.Caffeine.Guava.Redis等. 二.缓存注解 @EnableCaching:开启缓存功能 @Cacheable:定义缓存,用于触发缓存 @CachePut:定义更新缓存,触发缓存更新 @CacheEvict:定义

  • 基于Spring Cache实现Caffeine+Redis二级缓存

    目录 一.聊聊什么是硬编码使用缓存? 二.Spring Cache简介 1.Cache接口 2.CacheManager接口 3.常用注解说明 三.使用二级缓存需要思考的一些问题? 四.Caffeine 简介 1.写入缓存策略 2.缓存值的清理策略 3.统计 4.高效的缓存淘汰算法 5.其他说明 五.基于Spring Cache实现二级缓存(Caffeine+Redis) 1.maven引入使用 2.application.yml 3.启动类上增加@EnableCaching 4.在需要缓存的方

  • 基于Spring接口集成Caffeine+Redis两级缓存

    目录 前言 改造 JSR107 规范 Cache CacheManager 配置&使用 分布式环境改造 定义消息体 Redis消息配置 消息消费逻辑 修改DoubleCache 测试 总结 前言 在上一篇文章Redis+Caffeine两级缓存的实现中,我们介绍了3种整合Caffeine和Redis作为两级缓存使用的方法,虽然说能够实现功能,但实现手法还是太粗糙了,并且遗留了一些问题没有处理.本文将在上一篇的基础上,围绕两个方面进行进一步的改造: JSR107定义了缓存使用规范,spring中提

  • Spring Boot集成ShedLock分布式定时任务的实现示例

    一.ShedLock是什么? 官方地址:github.com/lukas-kreca- 以下是ShedLock锁提供者,通过外部存储实现锁,由下图可知外部存储集成的库还是很丰富的 本篇教程我们基于JdbcTemplate存储为例来使用ShedLock锁. 二.落地实现 1.1 引入依赖包 shedlock所需依赖包: <dependency> <groupId>net.javacrumbs.shedlock</groupId> <artifactId>she

  • spring boot注解方式使用redis缓存操作示例

    本文实例讲述了spring boot注解方式使用redis缓存操作.分享给大家供大家参考,具体如下: 引入依赖库 在pom中引入依赖库,如下 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> &l

  • Spring Boot集成netty实现客户端服务端交互示例详解

    前言 Netty 是一个高性能的 NIO 网络框架,本文主要给大家介绍了关于SpringBoot集成netty实现客户端服务端交互的相关内容,下面来一起看看详细的介绍吧 看了好几天的netty实战,慢慢摸索,虽然还没有摸着很多门道,但今天还是把之前想加入到项目里的 一些想法实现了,算是有点信心了吧(讲真netty对初学者还真的不是很友好......) 首先,当然是在SpringBoot项目里添加netty的依赖了,注意不要用netty5的依赖,因为已经废弃了 <!--netty--> <

  • Springboot 集成spring cache缓存的解决方案

    目录 一.为什么要做缓存 二.常用缓存操作流程 三.整合Spring Cache 四.在ArticleController类上实现一个简单的例子 五.更改Redis缓存的序列化方式 一.为什么要做缓存 提升性能 绝大多数情况下,关系型数据库select查询是出现性能问题最大的地方.一方面,select 会有很多像 join.group.order.like 等这样丰富的语义,而这些语义是非常耗性能的:另一方面,大多数应用都是读多写少,所以加剧了慢查询的问题. 分布式系统中远程调用也会耗很多性能,

  • 关于Spring Cache 缓存拦截器( CacheInterceptor)

    目录 Spring Cache 缓存拦截器( CacheInterceptor) spring cache常用的三种缓存操作 具体整个流程是这样的 CacheInterceptor.java 定义Cacheable注解 定义Rediskey.java Cache.java RedisCache.java CacheManager.java AbstractCacheManager.java RedisCacheManager.java 实现CacheInterceptor.java 配置Spri

  • 如何扩展Spring Cache实现支持多级缓存

    为什么多级缓存 缓存的引入是现在大部分系统所必须考虑的 redis 作为常用中间件,虽然我们一般业务系统(毕竟业务量有限)不会遇到如下图 在随着 data-size 的增大和数据结构的复杂的造成性能下降,但网络 IO 消耗会成为整个调用链路中不可忽视的部分.尤其在 微服务架构中,一次调用往往会涉及多次调用 例如pig oauth2.0 的 client 认证 Caffeine 来自未来的本地内存缓存,性能比如常见的内存缓存实现性能高出不少详细对比. 综合所述:我们需要构建 L1 Caffeine

随机推荐