Spring @Cacheable缓存注解

一、简介

缓存介绍

缓存,在我们的日常开发中用的非常多,是我们应对各种性能问题支持高并发的一大利器。

  • Spring 从 3.1 开始就引入了缓存的支持。定义了如下两个接口来统一支持不同的缓存技术。

    • org.springframework.cache.Cache
    • org.springframework.cache.CacheManager
  • 我们熟知的缓存有:堆缓存(Ehcache3.xGuava CacheCaffeine等)、堆外缓存(Ehcache3.xMapDB等)、分布式缓存RedisMemcached等)等等。

  • 常用的缓存注解:@EnableCaching@Cacheable@CachePut@CacheEvict

Cache 和 CacheManager 接口说明

  • Cache 接口包含缓存的各种操作集合,你操作缓存就是通过这个接口来操作的。
  • Cache 接口下 Spring 提供了各种 xxxCache 的实现,比如:RedisCache、EhCache、ConcurrentMapCache等。
  • CacheManager 定义了创建、配置、获取、管理和控制多个唯一命名的 Cache。这些 Cache 存在于 CacheManager 的上下文中。

二、缓存实战

1.开启缓存

在 SpringBoot 的启动类上添加注解@EnableCaching

2.@Cacheable

@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存。

常用属性:

  • cacheNamesvalue:用来指定缓存组件名称。

    复制代码
    @Cacheable(cacheNames = "users", key="#id")
    public User getUser(Integer id) {}
  • key:缓存数据的 key,可以用它来指定。默认使用所有参数的值进行组合。(key可以使用 spEL 表达式来编写)。

    复制代码
    @Cacheable(cacheNames = "usersBySpEL", key="#root.methodName + '[' + #id + ']'")
    public User getUserBySpEL(Integer id) {}
  • keyGenerator:key 的生成器。key 和 keyGenerator 二选一使用。

    复制代码
    @Cacheable(cacheNames = "userByKeyGenerator", keyGenerator = "myKeyGenerator")
    public User getUserByKeyGenerator(Integer id) {}
  • condition:指定符合条件的情况下才缓存。

    复制代码
    @Cacheable(cacheNames = "userByCondition", condition = "#id > 1")
    public User getUserByCondition(Integer id) {}
  • unless:指定不符合条件的情况下才缓存。(可以获取到结果进行判断,通过 #result 获取方法结果,unless,汉语意思,除非,指会缓存,除了。。。之外)。

    复制代码
    @Cacheable(cacheNames = "userByUnless", unless = "#id > 1")
    public User getUserByUnless(Integer id) {}
  • sync:是否使用异步模式。

3.@CachePut

@CachePut 的作用 主要针对配置,能够根据方法的请求参数对其结果进行缓存。

  • 区别于 @Cacheable,它每次都会触发真实方法的调用,可以保证缓存的一致性。
  • 属性与 @Cacheable 类同。
复制代码
@CachePut(cacheNames = "users" , key = "#user.id")
public User addUser(User user) {}
4.@CacheEvict

@CacheEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空

常用属性

  • cacheNamesvalue:用来指定缓存组件名称。

  • key:缓存数据的 key,可以用它来指定。默认使用所有参数的值进行组合。(key可以使用 spEL 表达式来编写)。

  • condition:指定符合条件的情况下的缓存。

  • allEntries:是否清空所有缓存,缺省为false。

  • beforeInvocation:是否在方法执行前就清空,缺省为false,缺省情况下,如果方法执行抛异常,则不会清空缓存。

    @CacheEvict(cacheNames = "users", key = "#id")
    public void delUserCache(Integer id) {}

5.@CacheConfig

@CacheConfig 的作用 主要针对类配置,能够设置当前类中 @Cacheable 的 value 属性默认值。当然如果 @Cacheable 设置了 value,还是以设置的值为准。

常用属性

  • cacheNames: 指定缓存名称默认值。
6.@Caching

@Caching 的作用 主要针对方法配置,能够组合多个Cache注解。比如用户新增成功后,我们可能需要添加 id -> user、username -> user、email -> user 的缓存,此时就需要 @Caching 组合多个注解标签了。

常用属性

  • cacheable:组合多个 @Cacheable 注解

  • put:组合多个 @CachePut 注解

  • evict:组合多个 @CacheEvict 注解

    @CacheConfig(cacheNames = "users")
    public class CacheTestServiceImpl implements CacheTestService {
    /**
    * @Cacheable 的 cacheNames 默认为 "users"
    */
    @Cacheable(key="#id")
    public User getUser(Integer id) {...}
    }

7.自定义缓存过期时间

7.1 设置全局默认缓存过期时间:

复制代码
    // 提供默认的cacheManager,应用于全局,实现存活2天
    @Bean
    @Primary
    public CacheManager defaultCacheManager(
            RedisTemplate<?, ?> redisTemplate) {
        RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(redisTemplate.getConnectionFactory());
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(2));
        return new RedisCacheManager(writer, config);
    }

7.2 定制部分缓存过期时间

  • 定制缓存过期时间,需要自定义RedisCacheManager来实现ttl设置。

  • 注意:项目中如已配置了RedisCacheManager需要在原配置的bean上添加注解 @Primary,以免造成干扰

    复制代码
      /**
      	自定义RedisCacheManager,用于在使用@Cacheable时设置ttl
       */
      @Bean
      public RedisCacheManager selfCacheManager(RedisTemplate<String, Object> redisTemplate) {
      	RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());
      	RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
      			.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
      	return new SelfRedisCacheManager(redisCacheWriter, redisCacheConfiguration);
      }

SelfRedisCacheManager.java

复制代码
public class SelfRedisCacheManager extends RedisCacheManager {
    public SelfRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
        super(cacheWriter, defaultCacheConfiguration);
    }

    @Override
    protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
        String[] cells = StringUtils.delimitedListToStringArray(name, "=");
        name = cells[0];
        if (cells.length > 1) {
            long ttl = Long.parseLong(cells[1]);
            // 根据传参设置缓存失效时间,默认单位是秒
            cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl));
        }
        return super.createRedisCache(name, cacheConfig);
    }
}

使用:

复制代码
// value、cacheNames是等效的,ttl=600s,unless是不缓存的结果(为null时不缓存)
@Cacheable(value = "p_user=600",key = "#menu+'_'+#type+'_'+#userId",cacheManager = "selfCacheManager", unless = "#result == null")
public User getUser(...){
    xxx
}

// 当前方法执行时对应的key失效,也可以用@CachePut在当前方法执行时更新key
@CacheEvict(cacheNames = "p_user",key = "#p.menu+'_'+#p.type+'_'+#p.user")
public boolean setUser(User p){
    xxx
}

三、spEL表达式

参考地址:

1.@Cacheable设置过期时间:https://blog.csdn.net/weixin_41860719/article/details/125226096

相关推荐
IT毕设实战小研6 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
一只爱撸猫的程序猿7 小时前
使用Spring AI配合MCP(Model Context Protocol)构建一个"智能代码审查助手"
spring boot·aigc·ai编程
甄超锋7 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
武昌库里写JAVA10 小时前
JAVA面试汇总(四)JVM(一)
java·vue.js·spring boot·sql·学习
Java小白程序员11 小时前
Spring Framework:Java 开发的基石与 Spring 生态的起点
java·数据库·spring
Pitayafruit11 小时前
Spring AI 进阶之路03:集成RAG构建高效知识库
spring boot·后端·llm
zru_960211 小时前
Spring Boot 单元测试:@SpyBean 使用教程
spring boot·单元测试·log4j
甄超锋11 小时前
Java Maven更换国内源
java·开发语言·spring boot·spring·spring cloud·tomcat·maven
还是鼠鼠12 小时前
tlias智能学习辅助系统--Maven 高级-私服介绍与资源上传下载
java·spring boot·后端·spring·maven
还是大剑师兰特14 小时前
Spring面试题及详细答案 125道(1-15) -- 核心概念与基础1
spring·大剑师·spring面试题·spring教程