如何使用Spring Cache设置缓存条件操作
发表于:2025-01-22 作者:千家信息网编辑
千家信息网最后更新 2025年01月22日,这篇文章将为大家详细讲解有关如何使用Spring Cache设置缓存条件操作,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Spring Cache设置缓存条件原理从
千家信息网最后更新 2025年01月22日如何使用Spring Cache设置缓存条件操作
这篇文章将为大家详细讲解有关如何使用Spring Cache设置缓存条件操作,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
Spring Cache设置缓存条件
原理
从Spring3.1开始,Spring框架提供了对Cache的支持,提供了一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种 annotation,即能够达到缓存方法的返回对象的作用。
提供的主要注解有@Cacheable、@CachePut、@CacheEvict和@Caching,具体见下表:
注解 | 说明 |
---|---|
@Cacheable | 可以标注在类或方法上:标注在方法上表示该方法支持数据缓存;标在类上表示该类的所有方法都支持数据缓存。 具体功能:在执行方法体之前,检查缓存中是否有相同key值的缓存存在,如果存在对应的缓存,直接返回缓存中的值;如果不存在对应的缓存,则执行相应的方法体获取数据,并将数据存储到缓存中。 |
@CachePut | 可以标注在类或方法上,表示支持数据缓存。 具体功能:在方法执行前不会检查缓存中是否存在相应的缓存,而是每次都会执行方法体,并将方法执行结果存储到缓存中,如果相应key值的缓存存在,则更新key对应的value值。 |
@CacheEvict | 可以标注在类或方法上,用于清除相应key值的缓存。 |
@Caching | 可以标注在类或方法上,它有三个属性cacheable、put、evict分别用于指定@Cacheable、@CachePut和@CacheEvict |
当需要在类上或方法上同时使用多个注解时,可以使用@Caching,如:
@Caching(cacheable=@Cacheable("User"), evict = {@CacheEvict("Member"), @CacheEvict(value = "Customer", allEntries = true)})
@Cacheable的常用属性及说明
如下表所示:
@Cacheable属性 | 说明 |
---|---|
key | 表示缓存的名称,必须指定且至少要有一个值,比如:@Cacheable(value="Dept")或@Cacheable(value={"Dept","Depts"}) |
condition | 表示是否需要缓存,默认为空,表示所有情况都会缓存。通过SpEL表达式来指定,若condition的值为true则会缓存,若为false则不会缓存,如@Cacheable(value="Dept",key="'deptno_'+# deptno ",condition="#deptno<=40") |
value | 表示缓存的key,支持SpEL表达式,如@Cacheable(value="Dept",key="'deptno_' +#deptno"),可以不指定值,如果不指定,则缺省按照方法的所有参数进行组合。除了上述使用方法参数作为key之外,Spring还提供了一个root对象用来生成key,使用方法如下表所示,其中"#root"可以省略。 |
Root对象
Root对象 | 说明 |
---|---|
methodName | 当前方法名,比如#root.methodName |
method | 当前方法,比如#root.method.name |
target | 当前被调用的对象,比如#root.target |
targetClass | 当前被调用的对象的class,比如#root.targetClass |
args | 当前方法参数组成的数组,比如#root.args[0] |
caches | 当前被调用的方法使用的缓存,比如#root.caches[0].name |
@CachePut的常用属性同@Cacheable
@CacheEvict的常用属性如下表所示:
@CacheEvict属性 | 说明 |
---|---|
value | 表示要清除的缓存名 |
key | 表示需要清除的缓存key值, |
condition | 当condition的值为true时才清除缓存 |
allEntries | 表示是否需要清除缓存中的所有元素。默认为false,表示不需要,当指定了allEntries为true时,将忽略指定的key。 |
beforeInvocation | 清除操作默认是在方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当该属性值为true时,会在调用该方法之前清除缓存中的指定元素。 |
示例:设置当 dname 的长度大于3时才缓存
//条件缓存@ResponseBody@GetMapping("/getLocByDname")@Cacheable(cacheNames = "dept", key = "#dname", condition = "#dname.length()>3")public String getLocByDname(@RequestParam("dname") String dname) {//key动态参数 QueryWrapperqueryMapper = new QueryWrapper<>(); queryMapper.eq("dname", dname); Dept dept = deptService.getOne(queryMapper); return dept.getLoc();}
示例:unless 即条件不成立时缓存
#result 代表返回值,意思是当返回码不等于 200 时不缓存,也就是等于 200 时才缓存。
@ResponseBody@GetMapping("/getDeptByDname")@Cacheable(cacheNames = "dept", key = "#dname", unless = "#result.code != 200")public ResultgetDeptByDname(@RequestParam("dname") String dname){//key动态参数 QueryWrapper queryMapper = new QueryWrapper<>(); queryMapper.eq("dname", dname); Dept dept = deptService.getOne(queryMapper); if (dept == null) return ResultUtil.error(120, "dept is null"); else return ResultUtil.success(dept);}
Cache缓存配置
1、pom.xml
org.springframework.boot spring-boot-starter-cache org.springframework.boot spring-boot-starter-aop org.reflections reflections 0.9.11
2、Ehcache配置文件
3、配置类
@Configuration@EnableCachingpublic class CustomConfiguration { /** * @see org.springframework.cache.interceptor.SimpleKeyGenerator * Generate a key based on the specified parameters. */ public static Object generateKey(Object... params) { if (params.length == 0) { return SimpleKey.EMPTY; } if (params.length == 1) { Object param = params[0]; if (param != null && !param.getClass().isArray()) { return param; } } return new SimpleKey(params); }/** * 若将target作为key的一部分时,CGLIB动态代理可能导致重复缓存 * 注意:返回的key一定要重写hashCode()和toString(),防止key对象不一致导致的缓存无法命中 * 例如:ehcache 底层存储net.sf.ehcache.store.chm.SelectableConcurrentHashMap#containsKey */ @Bean public KeyGenerator customKeyGenerator(){ return (target, method, params) -> { final Object key = generateKey(params); StringBuffer buffer = new StringBuffer(); buffer.append(method.getName()); buffer.append("::"); buffer.append(key.toString());// 注意一定要转为String,否则ehcache key对象可能不一样,导致缓存无法命中 return buffer.toString(); }; } /** * redis缓存管理器 */ @Bean @ConditionalOnBean(RedisConfiguration.class) @ConditionalOnProperty(prefix = "spring.cache", name = "type", havingValue = "redis", matchIfMissing = false) public CacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())) .entryTtl(Duration.ofMinutes(10)); return RedisCacheManager .builder(RedisCacheWriter.lockingRedisCacheWriter(redisConnectionFactory)) .cacheDefaults(config).build(); }/** * ehcache缓存管理器(默认) * default XML files {@link net.sf.ehcache.config.ConfigurationFactory#parseConfiguration()} */ @Bean @ConditionalOnProperty(prefix = "spring.cache", name = "type", havingValue = "ehcache", matchIfMissing = true) public CacheManager ehcacheCacheManager() { net.sf.ehcache.CacheManager cacheManager = net.sf.ehcache.CacheManager.create(); /** * 包扫描查找指定注解并将cacheNames添加到net.sf.ehcache.CacheManager(单例) */ Reflections reflections = new Reflections("com.example.demo.service", new TypeAnnotationsScanner() , new SubTypesScanner(), new MethodAnnotationsScanner()); Set> classesList = reflections.getTypesAnnotatedWith(CacheConfig.class); for (Class> aClass : classesList) { final CacheConfig config = AnnotationUtils.findAnnotation(aClass, CacheConfig.class); if (config.cacheNames() != null && config.cacheNames().length > 0) { for (String cacheName : config.cacheNames()) { cacheManager.addCacheIfAbsent(cacheName); } } } /** * 方法级别的注解 @Caching、@CacheEvict、@Cacheable、@CachePut,结合实际业务场景仅扫描@Cacheable即可 */ final Set methods = reflections.getMethodsAnnotatedWith(Cacheable.class); for (Method method : methods) { final Cacheable cacheable = AnnotationUtils.findAnnotation(method, Cacheable.class); if (cacheable.cacheNames() != null && cacheable.cacheNames().length > 0) { for (String cacheName : cacheable.cacheNames()) { cacheManager.addCacheIfAbsent(cacheName); } } } EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager(); ehCacheCacheManager.setCacheManager(cacheManager); return ehCacheCacheManager; }}
4、示例
@Component@CacheConfig(cacheNames = "XXXServiceImpl", keyGenerator = "customKeyGenerator")public class XXXServiceImpl extends ServiceImplimplements XXXService { @CacheEvict(allEntries = true) public void evictAllEntries() {} @Override @Cacheable public List findById(Long id) { return this.baseMapper.selectList(new QueryWrapper ().lambda() .eq(XXXEntity::getId, id)); }}
关于"如何使用Spring Cache设置缓存条件操作"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
缓存
方法
对象
属性
条件
参数
数据
注解
支持
动态
常用
示例
篇文章
并将
存储
配置
成功
使用方法
元素
功能
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
软件开发生命周期有哪些
ios 数据库 第三方
软件开发的原型法
丹江口信息软件开发学习
ue4为服务器节点
软件开发需求导图
云顶之弈2022无法连接服务器
公共资源电子化网络安全问题
香港服务器怎么设置域名
方舟生存进化服务器怎么看雷达
软件开发 sde 有哪些
浏览器程序检查功能查看数据库表
中国知网数据库三种进入途径
朝阳区威力软件开发配置
服务器和网站有关吗
数据库理论课答案
服务器需要散热的温度
数据库应用小视频教程
联想服务器启动后声音很大
萤火突击怎样换服务器
mysql数据库关联关系
数据库奥特兰负酒犬
网络技术周跃
体育对冲软件开发
软件开发项目负责人简历
计算机网络技术专业女生就业
abi数据库包括哪国语言
芜湖网线网络技术公司
网络安全页面展示数据
如何让服务器不崩溃