SpringCache 缓存

Spring Cache 简介

Spring Cache 是 Spring Framework 3.1 开始引入的一个新特性,它提供了一套强大的缓存管理功能,支持多种缓存技术,如:EhCache、Redis、Hazelcast、Guava 等。

Spring Cache 是基于注解的缓存管理功能,通过在方法上添加注解,就可以将方法的返回值缓存到缓存中,下次调用时,如果缓存存在,直接读取缓存数据返回;如果缓存不存在,则调用方法,并把返回结果存入缓存中。

Spring Cache 提供了一系列的注解,用于在方法上添加缓存功能,主要包括以下几个注解:

  • @EnableCaching:开启缓存功能

  • @CacheConfig:在类上配置缓存的一些公共属性

  • @Cacheable:缓存方法的返回结果

  • @CachePut:更新缓存,即调用方法后,将返回结果更新到缓存中

  • @CacheEvict:清除缓存

  • @Caching:组合多个缓存注解

CacheManager 是 Spring Cache 的核心接口,它定义了缓存操作的一些基本方法,如:获取缓存、清除缓存等。Spring Cache 提供了多种 CacheManager 的实现,如:SimpleCacheManager、ConcurrentMapCacheManager、EhCacheCacheManager、RedisCacheManager 等。

CacheManager
描述

SimpleCacheManager

简单的 CacheManager 实现,它可以管理多个缓存对象,每个缓存对象都是一个 Cache 对象,它们之间是相互独立的。

ConcurrentMapCacheManager

基于 ConcurrentHashMap 实现的 CacheManager,它可以管理多个缓存对象,每个缓存对象都是一个 ConcurrentMapCache 对象,它们之间是相互独立的。

EhCacheCacheManager

基于 EhCache 实现的 CacheManager,它可以管理多个缓存对象,每个缓存对象都是一个 EhCacheCache 对象,它们之间是相互独立的。

RedisCacheManager

基于 Redis 实现的 CacheManager,它可以管理多个缓存对象,每个缓存对象都是一个 RedisCache 对象,它们之间是相互独立的。

HazelcastCacheManager

基于 Hazelcast 实现的 CacheManager,它可以管理多个缓存对象,每个缓存对象都是一个 HazelcastCache 对象,它们之间是相互独立的。

GuavaCacheManager

基于 Guava 实现的 CacheManager,它可以管理多个缓存对象,每个缓存对象都是一个 GuavaCache 对象,它们之间是相互独立的。

CouchbaseCacheManager

基于 Couchbase 实现的 CacheManager,它可以管理多个缓存对象,每个缓存对象都是一个 CouchbaseCache 对象,它们之间是相互独立的。

GemfireCacheManager

基于 Gemfire 实现的 CacheManager,它可以管理多个缓存对象,每个缓存对象都是一个 GemfireCache 对象,它们之间是相互独立的。

NoneCacheManager

空的 CacheManager 实现,它不会缓存任何数据。

@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        List<Cache> caches = new ArrayList<>();
        caches.add(new ConcurrentMapCache("user"));
        caches.add(new ConcurrentMapCache("role"));
        cacheManager.setCaches(caches);
        return cacheManager;
    }
}

@Cacheable

缓存方法的返回结果,可以把结果缓存到指定的缓存中,下次调用时,如果缓存存在,直接读取缓存数据返回;如果缓存不存在,则调用方法,并把返回结果存入缓存中。

属性
描述
示例

value

缓存的名称,必须指定至少一个

@Cacheable(value = "user")

key

缓存的 key,如果不指定,则按照方法的所有参数进行组合。指定时候要按照 SpEL 表达式编写

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

condition

缓存的条件,默认为空,使用 SpEL 编写,返回 true 才进行缓存/清除缓存

@Cacheable(value = "user", condition = "#id>0")

keyGenerator

缓存的 key 生成器,默认为空,表示使用 SimpleKeyGenerator 生成 key

@Cacheable(value = "user", keyGenerator = "myKeyGenerator")

cacheManager

缓存管理器,默认为空,表示使用默认的缓存管理器

@Cacheable(value = "user", cacheManager = "myCacheManager")

cacheResolver

缓存解析器,默认为空,表示使用默认的缓存解析器

@Cacheable(value = "user", cacheResolver = "myCacheResolver")

unless

否定缓存,默认为空,当结果为 true 时,不缓存结果,使用 SpEL 编写。

@Cacheable(value = "user", unless = "#result == null")

sync

是否使用异步模式

@Cacheable(value = "user", sync = true)

allEntries

是否清空所有缓存,默认为 false,如果指定为 true,则方法调用后立即清空所有缓存。

@Cacheable(value = "user", allEntries = true)

beforeInvocation

是否在方法执行前就清空,默认为 false,如果指定为 true,则在方法调用前清空缓存。

@Cacheable(value = "user", beforeInvocation = true)

// user::1000
@Cacheable(value = "user", key = "#id")
public User getUserById(Long id) {
    return userRepository.findById(id).orElse(null);
}
// SPeL 表达式,当 id>0 时才会缓存
@Cacheable(value = "user", key = "#id", condition = "#id>0")
public User getUserById(Long id) {
    return userRepository.findById(id).orElse(null);
}

SpEL 上下文

  • #root:代表当前被调用方法的参数,可以通过 #root.args[0] 获取第一个参数。通过 #root.methodName 获取方法名。通过 #root.target 获取目标对象。通过 #root.targetClass 获取目标对象的类。通过 #root.caches 获取缓存对象。

  • #result:代表方法调用的返回值,只有在方法执行完成后才能获取到返回值

  • #target:代表被调用的目标对象

  • #this:代表被调用的代理对象

当我们使用 root 对象的属性作为 key 时候,可以将 #root 省略,如:@Cacheable(value = "user", key = "#root.args[0]") 可以简写为 @Cacheable(value = "user", key = "#args[0]")

使用方法参数时,可以直接使用#参数名或者#p0#p1等表示方法的第一个参数、第二个参数等。例如:@Cacheable(value = "user", key = "#id") 可以简写为 @Cacheable(value = "user", key = "#p0")

@Cacheable(value = "user", key = "#id")
public User getUserById(Long id) {
    return userRepository.findById(id).orElse(null);
}

@CacheConfig

当我们需要缓存的地方越来越多,你可以使用@CacheConfig(cacheNames={"cacheName"})注解在 class 之上来统一指定缓存的名字,这时可省略 @Cacheable 注解中的 value 属性。

@CacheConfig(cacheNames = "user")
public class UserService {
    @Cacheable(key = "#id")
    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
}

@CachePut

@CachePut@Cacheable 类似,区别在于 @CachePut 每次都会调用方法,并将返回结果更新到缓存中,适用于更新缓存。

属性
描述
示例

value

缓存的名称,必须指定至少一个

@Cacheable(value = "user")

key

缓存的 key,如果不指定,则按照方法的所有参数进行组合。指定时候要按照 SpEL 表达式编写

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

condition

缓存的条件,默认为空,使用 SpEL 编写,返回 true 才进行缓存/清除缓存

@Cacheable(value = "user", condition = "#id>0")

keyGenerator

缓存的 key 生成器,默认为空,表示使用 SimpleKeyGenerator 生成 key

@Cacheable(value = "user", keyGenerator = "myKeyGenerator")

cacheManager

缓存管理器,默认为空,表示使用默认的缓存管理器

@Cacheable(value = "user", cacheManager = "myCacheManager")

cacheResolver

缓存解析器,默认为空,表示使用默认的缓存解析器

@Cacheable(value = "user", cacheResolver = "myCacheResolver")

unless

否定缓存,默认为空,当结果为 true 时,不缓存结果,使用 SpEL 编写。

@Cacheable(value = "user", unless = "#result == null")

sync

是否使用异步模式

@Cacheable(value = "user", sync = true)

allEntries

是否清空所有缓存,默认为 false,如果指定为 true,则方法调用后立即清空所有缓存。

@Cacheable(value = "user", allEntries = true)

beforeInvocation

是否在方法执行前就清空,默认为 false,如果指定为 true,则在方法调用前清空缓存。

@Cacheable(value = "user", beforeInvocation = true)

@CachePut(value = "user", key = "#user.id")
public User updateUser(User user) {
    return user;
}
// SPeL 表达式,当 user.id>0 时才会更新缓存
@CachePut(value = "user", key = "#user.id", condition = "#user.id>0")
public User updateUser(User user) {
    return user;
}

@CacheEvict

清除缓存,可以通过 key 指定要清除的缓存,allEntries = true 清除所有缓存。

属性
描述
示例

value

缓存的名称,必须指定至少一个

@Cacheable(value = "user")

key

缓存的 key,如果不指定,则按照方法的所有参数进行组合。指定时候要按照 SpEL 表达式编写

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

condition

缓存的条件,默认为空,使用 SpEL 编写,返回 true 才进行缓存/清除缓存

@Cacheable(value = "user", condition = "#id>0")

keyGenerator

缓存的 key 生成器,默认为空,表示使用 SimpleKeyGenerator 生成 key

@Cacheable(value = "user", keyGenerator = "myKeyGenerator")

cacheManager

缓存管理器,默认为空,表示使用默认的缓存管理器

@Cacheable(value = "user", cacheManager = "myCacheManager")

cacheResolver

缓存解析器,默认为空,表示使用默认的缓存解析器

@Cacheable(value = "user", cacheResolver = "myCacheResolver")

unless

否定缓存,默认为空,当结果为 true 时,不缓存结果,使用 SpEL 编写。

@Cacheable(value = "user", unless = "#result == null")

sync

是否使用异步模式

@Cacheable(value = "user", sync = true)

allEntries

是否清空所有缓存,默认为 false,如果指定为 true,则方法调用后立即清空所有缓存。

@Cacheable(value = "user", allEntries = true)

beforeInvocation

是否在方法执行前就清空,默认为 false,如果指定为 true,则在方法调用前清空缓存。

@Cacheable(value = "user", beforeInvocation = true)

@Caching

组合多个缓存注解,能够在一个方法上同时使用多个缓存注解。

@Caching(
    cacheable = {
        @Cacheable(value = "user", key = "#id")
    },
    put = {
        @CachePut(value = "user", key = "#result.id")
    }
)
public User getUserById(Long id) {
    return userRepository.findById(id).orElse(null);
}

SPeL 表达式介绍

Spring Expression Language(SpEL)是 Spring Framework 3.0 引入的一种表达式语言,它支持在运行时查询和操作对象图。SpEL 支持的功能包括:算术运算、逻辑运算、关系运算、正则表达式、类型运算、集合操作、数组操作、方法调用、变量引用、属性引用、构造函数引用、Bean 引用等。

SpEL 表达式的语法与 JavaScript、JSP 等语言类似,主要包括以下几种类型:

最后更新于

这有帮助吗?