springboot使用缓存(一)
一、概述
在实际项目中,我们经常遇到这种场景,一些数据更新频率不大,但是访问频繁,而且访问耗时比较长,就比如我的有些接口最长需要7秒才能返回。
虽然这个是有原因的,但这个时长依然是不能忍受的。
这种情况下,在springboot中使用缓存成为一种简单有效的方式。
说到缓存,就需要先确定,缓存到哪里,如果是单节点服务,推荐使用ehcache,如果是分布式服务,首选redis
这里以ehcache为例,描述下缓存的基本使用流程。
二、依赖
开启缓存需要依赖springboot的cache模块和ehcache,下面引入相关依赖
<!--缓存--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> <version>2.4.4</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.6</version> </dependency>
三、开启缓存
在入口类添加注解开启缓存
@EnableCaching @EnableSwagger2 @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
四、缓存配置
ehcache是两级缓存,第一级在内存,内存放不下就写入磁盘,项目中需要对一些基本配置项做配置,在resources目录下加入ehcache.xml文件,内容如下
<?xml version="1.0" encoding="UTF-8"?> <ehcache updateCheck="false" name="defaultCache"> <!-- 磁盘缓存位置 --> <diskStore path="java.io.tmpdir/ehcache"/> <!-- maxEntriesLocalHeap:堆内存中最大缓存对象数 eternal:对象是否永久有效,一但设置了,timeout将不起作用 overflowToDisk:当缓存达到maxElementsInMemory值是,是否允许溢出到磁盘 timeToIdleSeconds:当缓存闲置n秒后销毁 timeToLiveSeconds:当缓存存活n秒后销毁 maxEntriesLocalDisk:硬盘最大缓存个数 diskPersistent:磁盘缓存在JVM重新启动时是否保持 --> <!-- 默认缓存 --> <defaultCache maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="600" maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"/> <!-- fill-in缓存 --> <cache name="fillIn" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="600" overflowToDisk="false" memoryStoreEvictionPolicy="LRU"/> </ehcache>
五、java配置引用XML
import net.sf.ehcache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; @Configuration @EnableCaching public class CachingConfig { @Bean public EhCacheCacheManager cacheManager(CacheManager cm) { return new EhCacheCacheManager(cm); } @Bean public EhCacheManagerFactoryBean ehcache() { EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean(); cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml")); return cacheManagerFactoryBean; } }
六、缓存应用
哪些方法需要缓存呢,当然是哪些耗时最久的方法,比如我的某个service实现类中有个数据库查询方法queryData,开启缓存就需要如下配置
@Cacheable(value = "fillIn") @Override public List<Map<String, Object>> queryData(String tbName) { List<String> columns = columnsDao.selectColumns(tbName); List<Map<String, Object>> maps = dataDao.selectAll(tbName, columns); return maps; }
经过测试,第一次访问时长不变,之后接口的返回时长从数秒降低到数毫秒,效率提升了1000倍,真是太香了!
实践中发现有些无参数的方法加了缓存之后,没有生效,这种情况需要手动指定缓存的key
下面是一些官方指定的可以用作key的变量,可以直接拿来用
七、常用参数
有时候结果为null,显然这是有问题的,但如果也把null缓存起来,显然是错上加错。所以这种result就不能缓存,unless就是用来处理这种情况
@Cacheable(cacheNames = "bigScreen",unless = "#result == null")
标签:
Spring
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗