spring框架中的本地缓存之spring cache基本使用详解

 更新时间:2025年05月19日 09:25:05   作者:?abc!  
Spring Cache 是 Spring 提供的一整套的缓存解决方案,它提供了一整套的接口和代码规范、配置、注解等,这样它就可以整合各种缓存方案了,本文给大家介绍spring框架中的本地缓存之spring cache基本使用,感兴趣的朋友一起看看吧

基本概念及原理

处理逻辑

Spring Cache 是 Spring 提供的一整套的缓存解决方案

虽然它本身并没有提供缓存的实现,但是它提供了一整套的接口和代码规范、配置、注解等,这样它就可以整合各种缓存方案了

处理逻辑:

每次调用某方法,而此方法又是带有缓存功能时,Spring 框架就会检查指定参数的那个方法是否已经被调用过,如果之前调用过,就从缓存中取之前调用的结果;如果没有调用过,则再调用一次这个方法,并缓存结果,然后再返回结果,那下次调用这个方法时,就可以直接从缓存中获取结果了

实现步骤

SpringCache实现步骤 :

  • 启用缓存 :通过 @EnableCaching 注解触发 Spring 的缓存代理配置
  • AOP 拦截 :Spring 为标记注解的方法生成代理对象,在方法调用前后插入缓存操作。
  • 缓存处理 :根据注解配置,调用 CacheManager 获取 Cache 实例,执行读写或删除操作。

核心原理

Spring Cache 的核心原理基于 AOP(面向切面编程) 和 缓存抽象 ,通过注解简化缓存逻辑的集成。

核心是 缓存抽象层 和 动态代理机制 ,结合 Spring Boot 的自动配置,可快速集成多种缓存方案,显著提升系统性能

Spring Cache 通过 抽象层 解耦具体缓存技术

  • 适配器模式 :通过 CacheManager 和 Cache 接口适配不同缓存实现(如 Redis、Ehcache)。
  • 自动配置 :Spring Boot 的 spring-boot-autoconfigure 模块自动检测并配置缓存实现(如引入 spring-boot-starter-data-redis 后自动启用 Redis 缓存)。

核心组件与抽象

Cache 接口 :定义缓存操作(如 get、put、evict),具体实现由第三方缓存技术(如 Redis、Caffeine)提供。

CacheManager 接口 :管理多个 Cache 实例,负责创建、配置和获取缓存对象

例如:

ConcurrentMapCacheManager(默认内存缓存)RedisCacheManager(Redis 实现)EhCacheCacheManager(Ehcache 实现)

核心注解

Spring 提供了五个注解来声明缓存规则。

@Cacheable:方法执行前检查缓存,命中则直接返回,否则执行方法并缓存结果。
@CachePut:方法调用前不会去缓存中查找,无论缓存是否存在,都执行方法并更新缓存。
@CacheEvict:删除指定缓存,清除缓存中的一条或多条记录
@Caching:组合多个缓存操作。
@CacheConfig:在类级别共享相同的缓存的配置

注解作用常用参数
@Cacheable方法结果缓存(先查缓存,未命中执行方法),一般用在查询方法上value, key, condition
@CachePut强制更新缓存(始终执行方法),一般用在新增方法上value, key, unless
@CacheEvict清除缓存,一般用在更新或者删除方法上value, key, allEntries
@Caching组合多个缓存操作,实现同一个方法上同时使用多种注解cacheable, put, evict
@CacheConfig类级别共享缓存配置cacheNames, keyGenerator

SpEL 表达式

场景表达式示例
防缓存穿透unless = “#result == null”
多字段复合键key = “#user.id + ‘:’ + #user.deviceId”
时间戳动态键key = “T(System).currentTimeMillis()”
权限过滤condition = “#authLevel > 3”
集合非空判断condition = “!#list.isEmpty()”

实现

pom依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

选择使用的缓存

# 使用redis进行缓存
spring.cache.type=redis

Spring Cache 支持很多缓存中间件作为框架中的缓存,总共有 9 种选择:

  • caffeine:Caffeine 是一种高性能的缓存库,基于 Google Guava。
  • couchbase:CouchBase是一款非关系型JSON文档数据库。
  • generic:由泛型机制和 static 组合实现的泛型缓存机制。
  • hazelcast:一个高度可扩展的数据分发和集群平台,可用于实现分布式数据存储、数据缓存。
  • infinispan:分布式的集群缓存系统。
  • jcache:JCache 作为缓存。它是 JSR107 规范中提到的缓存规范。
  • none:没有缓存。
  • redis:用 Redis 作为缓存
  • simple:用内存作为缓存

基本概念

启动类上面添加@EnableCaching注解

指定某方法开启缓存功能。在方法上添加 @Cacheable 缓存注解就可以了

@Cacheable 注解中,可以添加四种参数:value,key,condition,unless

  • value:指定缓存名称(必填)
  • key:自定义缓存键(SpEL表达式)
  • condition:执行前条件判断(SpEL)
  • unless:执行后结果过滤(SpEL)
参数类型作用示例
valueString[]指定缓存名称(必填)value = “users” 或 value = {“cache1”, “cache2”}
keyString自定义缓存键(SpEL表达式)key = "#userId"或key = “T(java.util.UUID).randomUUID().toString()”
conditionString执行前条件判断(SpEL)condition = "#userId > 1000"或condition = “#name.startsWith(‘admin’)”
unlessString执行后结果过滤(SpEL)unless = "#result == null"或unless = “#result.age < 18”

使用示例1

第一次调用下面这个接口前,缓存里面是没有hot缓存,也没有这个test方法的结果缓存

调用test方法后,缓存中便会创建出hot这个缓存,其中缓存了一个key(默认值SimpleKey[]),其中有一个值

  • 缓存中 key 对应的 value 默认使用 JDK 序列化后的数据。
  • value 的过期时间为 -1,表示永不过期。

key:hot:SimpleKey[]
value:222

@RequestMapping("/test2")
@Cacheable({"hot"})
public int test() {
    return 222;
}

第二次调用test()方法时,便会直接读缓存,而不去执行test里面的方法

@RequestMapping("/test2")
@Cacheable({"hot"})
public int test2() {
    return 456;
}

如果再将类名改为test2后,缓存获取到的值还是test方法时缓存的值222,因为两个方法的key值都是SimpleKey[]

使用示例2

// 启用缓存(配置类)
@EnableCaching
@Configuration
public class CacheConfig {
    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("users"); // 内存缓存
    }
}
// 业务层使用
@Service
public class UserService {
    // 缓存读取(value=缓存名称,key=缓存键)
    @Cacheable(value = "users", key = "#userId")
    public User getUserById(Long userId) {
        // 实际数据库查询
        return userRepository.findById(userId);
    }
    // 缓存更新
    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) {
        return userRepository.save(user);
    }
    // 缓存清除
    @CacheEvict(value = "users", key = "#userId")
    public void deleteUser(Long userId) {
        userRepository.deleteById(userId);
    }
}

自定义配置类

自定义缓存过去时间等

# 使用 Redis 作为缓存组件
spring.cache.type=redis
# 缓存过期时间为 3600s
spring.cache.redis.time-to-live=3600000
# 缓存的键的名字前缀
spring.cache.redis.key-prefix=passjava_
# 是否使用缓存前缀
spring.cache.redis.use-key-prefix=true
# 是否缓存控制,防止缓存穿透
spring.cache.redis.cache-null-values=true

自定义 key

在 @Cacheable 注解里面加上 key 的值 #root.method.name。这是一种特有的表达式,称作 SpEL 表达式,这里代表用方法名作为缓存 key 的名字

@Cacheable(value = {"hot"}, key = "#root.method.name")

如果按上述去配置的话,缓存的key的名称便是这个方法名

自定义条件

可以自定义条件来决定是否将缓存功能关闭。这里就要用到@Cacheable 另外两个属性:condition 和 unless,它俩的格式还是用 SpEL 表达式

到此这篇关于spring框架中的本地缓存:spring cache基本使用的文章就介绍到这了,更多相关spring cache使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java数组常用排序算法实例小结

    Java数组常用排序算法实例小结

    这篇文章主要介绍了Java数组常用排序算法,结合实例形式总结分析了java数组常用的4种排序算法,包括冒泡排序、数组递增排序、快速排序及选择排序,需要的朋友可以参考下
    2017-12-12
  • SpringMVC通过注解实现全局异常处理问题小结

    SpringMVC通过注解实现全局异常处理问题小结

    文章介绍SpringMVC全局异常处理机制,通过@ControllerAdvice和@ExceptionHandler注解实现统一异常处理,提升代码可维护性与响应一致性,减少重复try-catch代码,增强系统健壮性,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2025-09-09
  • PowerJob Alarmable工作流程源码剖析

    PowerJob Alarmable工作流程源码剖析

    这篇文章主要为大家介绍了PowerJob Alarmable工作流程源码剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Mybatis-plus对单表操作的封装实现

    Mybatis-plus对单表操作的封装实现

    本文详细介绍了MyBatis-Plus单表操作,包括自定义SQL、逻辑删除、乐观锁、全局拦截器和代码生成器等,具有一定的参考价值,感兴趣的可以了解一下
    2024-12-12
  • springboot项目事务标签验证

    springboot项目事务标签验证

    本文主要介绍了springboot项目事务标签验证,文中通过示例代码介绍的非常详细,详细的介绍了不加事务标签和加事物标签的使用,需要的朋友们下面随着小编来一起学习学习吧
    2021-07-07
  • Java中替代equals,compareTo和toString的方法

    Java中替代equals,compareTo和toString的方法

    这篇文章主要介绍了Java中替代equals,compareTo和toString的方法,文中代码十分详细,帮助大家更好的理解的学习,感兴趣的朋友可以了解下
    2020-06-06
  • 详细聊一聊java中封装的那点事

    详细聊一聊java中封装的那点事

    封装是一个非常广泛的概念,小到一个属性的封装,大到一个框架或者一个项目的封装,下面这篇文章主要给大家介绍了关于java中封装的那点事,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • Maven清理java项目中未使用到 jar 依赖包的方法

    Maven清理java项目中未使用到 jar 依赖包的方法

    本文主要介绍了Maven清理java项目中未使用到 jar 依赖包的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02
  • Java骚操作之CountDownLatch代码详解

    Java骚操作之CountDownLatch代码详解

    这篇文章主要介绍了Java骚操作之CountDownLatch代码详解,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • 详解JavaWeb中的过滤器Filter

    详解JavaWeb中的过滤器Filter

    今天给大家讲一下JavaWeb中的过滤器Filter,文中有非常详细的代码示例,对正在学习java的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05

最新评论