如何使用Spring Cache设置缓存条件操作
发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章将为大家详细讲解有关如何使用Spring Cache设置缓存条件操作,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Spring Cache设置缓存条件原理从
千家信息网最后更新 2026年11月04日如何使用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安全错误
数据库的锁怎样保障安全
湖南永感互联网科技有限公司
互联网扶贫科技
平安科技 互联网
万易互联网科技有限公司
互联网科技媒体
云电互联网科技
善班互联网科技有限公司
深圳天众互联网科技公司
上游互联网科技
互联网高科技股票
互联网科技视频素材
恒生科技互联网指数分析
新华互联网科技2019
昊天互联网科技有限公司
青岛科技大学互联网大赛研究生
民营互联网公司国防科技
明优互联网科技有限公司
中天科技中国工业互联网
互联网科技收购价值
互联网时代高科技布局
蓝思科技飞鸽互联网
互联网科技巨头监管
互联网电商科技
撒么互联网科技公司
深圳市运趣互联网科技有限公司
湖南一路畅行互联网科技
米聚互联网科技南京有限公司排面
雨阳互联网卡科技有限公司
互联网科技股为什么大涨
互联网科技数字货币