如何使用Spring Cache设置缓存条件操作
发表于:2025-11-17 作者:千家信息网编辑
千家信息网最后更新 2025年11月17日,这篇文章将为大家详细讲解有关如何使用Spring Cache设置缓存条件操作,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Spring Cache设置缓存条件原理从
千家信息网最后更新 2025年11月17日如何使用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动态参数 QueryWrapper queryMapper = 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 Result getDeptByDname(@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安全错误
数据库的锁怎样保障安全
人工智能是互联网科技吗
qt 怎么打开mysql数据库
佛山市顺德区合意软件开发
数据库设计的实训目的任务
语文网络安全手抄报
本地app软件开发公司
重量传感器与串口服务器
李沧区软件开发哪家靠谱
海康服务器管理接口
剑与契约服务器初始化
全国大学生网络安全测试大赛
数据库建立表格时怎么赋初值
数据库中使用索引的语句
单位装专用的网络安全零信任安全
中软酒店管理系统服务器
软件开发排期计划表
部队关于网络安全的标语
福建省高院网络安全
小学生网络安全知识ppt
上海正规软件开发服务参考价格
县网络安全宣传活动周
9.0服务器不显示角色
重量传感器与串口服务器
et是什么数据库
玉泉网络技术
网络技术市场需求
天津易狐网络技术有限公司
峰哥讲数据库视频
国家推动网络安全社会化
四川蒲江网络安全宣传周