一、简介
- Cache 接口包含缓存的各种操作集合,你操作缓存就是通过这个接口来操作的。
- Cache 接口下 Spring 提供了各种 xxxCache 的实现,比如:RedisCache、EhCache、ConcurrentMapCache等。
- CacheManager 定义了创建、配置、获取、管理和控制多个唯一命名的 Cache。这些 Cache 存在于 CacheManager 的上下文中。
二、缓存实战
1.开启缓存
在 SpringBoot 的启动类上添加注解@EnableCaching
。
2.@Cacheable
常用属性:
-
@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) {}
-
@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) {}
3.@CachePut
@CachePut(cacheNames = "users" , key = "#user.id")
public User addUser(User user) {}
4.@CacheEvict
常用属性
cacheNames
、value
:用来指定缓存组件名称。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,还是以设置的值为准。
常用属性
6.@Caching
@Caching
的作用 主要针对方法配置,能够组合多个Cache注解
。比如用户新增成功后,我们可能需要添加 id -> user、username -> user、email -> user 的缓存,此时就需要@Caching
组合多个注解标签了。
常用属性
@CacheConfig(cacheNames = "users")
public class CacheTestServiceImpl implements CacheTestService {
/**
* @Cacheable 的 cacheNames 默认为 "users"
*/
@Cacheable(key="#id")
public User getUser(Integer id) {...}
}
7.自定义缓存过期时间
// 提供默认的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);
}
- 定制缓存过期时间,需要自定义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);
}
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
原文地址:https://blog.csdn.net/fygkchina/article/details/134726030
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_23612.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!