https://docs.spring.io/spring-framework/reference/integration/cache
如果配置了一种缓存数据源,启动类添加@EnableCaching后自动启用缓存,取默认配置。
要设置缓存的方法添加@Cacheable()
@Cacheable(value = "tests",key = "#root.targetClass + '.' + #root.methodName + #root.args")
redis中存储的key值格式:{key-prefix} + {value}:: + {key}
配置文件:
spring:
cache:
type: redis # 缓存类型
redis:
key-prefix: spring-cache # 缓存前缀
time-to-live: 20s # 过期时间
use-key-prefix: true # 是否使用前缀 默认true
cache-null-values: true # 是否缓存null值 默认true
enable-statistics: true # 是否开启缓存统计 默认false
并发时加锁,阻塞其他线程,直到计算完一次后更新
@Cacheable(cacheNames="foos", sync=true)
有时,一个方法可能不适合一直缓存(例如,它可能取决于给定的参数)。缓存注释通过 condition参数支持此类用例
eg:
@Cacheable(value = "tests",condition = "#msg.length() < 3")
public String test(String msg) {
System.out.println("未使用缓存");
return "测试成功" + msg;
}
还有一个unless参数,当方法执行完后判断unless,为true则进行缓存。
@CachePut
始终调用该方法并将其结果放入缓存中,可用在更新数据时更新缓存
用法和@Cacheable一样
除非@Cacheable和@CachePut的触发条件互斥,否则不要用在同一方法
@CacheEvict
用于删除缓存,可用在删除数据时删除缓存
用法和@Cacheable一样
allEntries,用于选择是否进行范围的删除,范围删除即直接根据value值来批量删,默认false
beforeInvocation,用于选择是否在执行方法前进行操作,默认false
@CacheEvict(value = "testes",key = "#msg",allEntries = true)
@Caching允许我们在一个方法上使用多个@Cacheable,@CachePut,@CacheEvict
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })
@CacheConfig
@CacheConfig(cacheNames = "tests")
方法上的相同配置会覆盖类上的配置
也可以自定义配置CacheManager,KeyGenerator,CacheResolver
配置类配置,关键字是缓存的name(value),而不是整个key
@Configuration
public class CacheConfig {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Bean
public CacheManager cacheManager() {
Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();
// 对 'tests' 设置 1 分钟的 TTL
cacheConfigurations.put("tests", ttl("1m"));
// 对 'cache2' 设置 5 小时的 TTL
cacheConfigurations.put("cache2", ttl("5h"));
return RedisCacheManager.builder(redisConnectionFactory)
.withInitialCacheConfigurations(cacheConfigurations)
.build();
}
private RedisCacheConfiguration ttl(String ttl) {
//Duration格式转换,生成配置
return RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.parse("PT" + ttl.toUpperCase()));
}
}
名字 | 地点 | 描述 | 例子 |
---|---|---|---|
methodName | 根对象 | 被调用的方法的名称 | #root.methodName |
method | 根对象 | 被调用的方法 | #root.method.name |
target | 根对象 | 被调用的目标对象 | #root.target |
targetClass | 根对象 | 被调用的目标的类 | #root.targetClass |
args | 根对象 | 用于调用目标的参数(作为数组) | #root.args[0] |
caches | 根对象 | 运行当前方法的缓存集合 | #root.caches[0].name |
参数名称 | 评估背景 | 任何方法参数的名称。 | #iban 或#a0 (您也可以使用#p0 或#p<#arg> 符号作为别名)。 |
result | 评估背景 | 方法调用的结果(要缓存的值)。unless 仅在表达式、cache put 表达式(计算key )或cache evict 表达式(当beforeInvocation 是false )中可用。对于受支持的包装器(例如 Optional ),#result 指的是实际对象,而不是包装器。 | #result |