一、概述
在實際項目中,我們經常遇到這種場景,一些數據更新頻率不大,但是訪問頻繁,而且訪問耗時比較長,就比如我的有些接口最長需要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的變量,可以直接拿來用