SpringBoot在annotation的層面實現了數據緩存的功能,基於Spring的AOP技術。全部的緩存配置只是在annotation層面配置,像聲明式事務同樣。java
Spring定義了CacheManager和Cache接口統一不一樣的緩存技術。其中CacheManager是Spring提供的各類緩存技術的抽象接口。而Cache接口包含緩存的各類操做。web
針對不一樣的緩存技術,須要實現不一樣的cacheManager,Spring定義了以下的cacheManger實現。spring
CacheManger | 描述 |
---|---|
SimpleCacheManager | 使用簡單的Collection來存儲緩存,主要用於測試 |
ConcurrentMapCacheManager | 使用ConcurrentMap做爲緩存技術(默認) |
NoOpCacheManager | 測試用 |
EhCacheCacheManager | 使用EhCache做爲緩存技術,之前在hibernate的時候常常用 |
GuavaCacheManager | 使用google guava的GuavaCache做爲緩存技術 |
HazelcastCacheManager | 使用Hazelcast做爲緩存技術 |
JCacheCacheManager | 使用JCache標準的實現做爲緩存技術,如Apache Commons JCS |
RedisCacheManager | 使用Redis做爲緩存技術 |
常規的SpringBoot已經爲咱們自動配置了EhCache、Collection、Guava、ConcurrentMap等緩存,默認使用ConcurrentMapCacheManager
。SpringBoot的application.properties配置文件,使用spring.cache前綴的屬性進行配置。apache
spring.cache.type=#緩存的技術類型 spring.cache.cache-names=應用程序啓動建立緩存的名稱 spring.cache.ehcache.config=ehcache的配置文件位置 spring.cache.infinispan.config=infinispan的配置文件位置 spring.cache.jcache.config=jcache配置文件位置 spring.cache.jcache.provider=當多個jcache實現類時,指定選擇jcache的實現類
加入註解 @EnableCaching緩存
註解 | 描述 |
---|---|
@Cacheable | 在調用方法以前,首先應該在緩存中查找方法的返回值,若是這個值可以找到,就會返回緩存的值。不然,這個方法就會被調用,返回值會放到緩存之中。 |
@CachePut | 將方法的返回值放到緩存中。在方法的調用前並不會檢查緩存,方法始終都會被調用。 |
@CacheEvict | 在緩存中清除一個或多個條目。 |
@Caching | 分組的註解,可以同時應用多個其餘的緩存註解。 |
在實際開發過程當中,存在不使用註解,須要本身添加緩存的狀況。下面就以Ehcache
爲例,簡單寫一下配置過程。springboot
引入springboot-cache
和ehcache
。須要注意,EhCache
不須要配置version
,SpringBoot的根pom已經集成了。app
<!-- 緩存 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <!-- ehcache --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency>
加入註解 @EnableCaching
ide
@SpringBootApplication @EnableCaching public class DemoApplication { }
在src\main\resources
目錄下,添加ehcache.xml
文件,內容見文末。spring-boot
# 配置ehcache緩存 spring.cache.type=ehcache # 指定ehcache配置文件路徑 spring.cache.ehcache.config=classpath:/ehcache.xml
注入SpringBoot自動配置的bean,org.springframework.cache.CacheManager
。
一個簡單的測試類:測試
package com.bbf.frame.test; import com.bbf.frame.Application; import org.apache.commons.lang3.StringUtils; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import javax.annotation.Resource; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK) public class TestCache { @Resource private CacheManager cacheManager; @Test public void cacheTest() { // 顯示全部的Cache空間 System.out.println(StringUtils.join(cacheManager.getCacheNames(), ",")); Cache cache = cacheManager.getCache("userCache"); cache.put("key", "123"); System.out.println("緩存成功"); String res = cache.get("key", String.class); System.out.println(res); } }
// 獲取EhCache的管理器 org.springframework.cache.ehcache.EhCacheCacheManager cacheCacheManager = (EhCacheCacheManager) cacheManager; net.sf.ehcache.CacheManager ehCacheManager = cacheCacheManager.getCacheManager(); net.sf.ehcache.Cache ehCache = ehCacheManager.getCache("userCache");
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation = "http://ehcache.org/ehcache.xsd" updateCheck = "false"> <!-- 指定一個文件目錄,當EHCache把數據寫到硬盤上時,將把數據寫到這個文件目錄下 --> <diskStore path = "java.io.tmpdir"/> <!-- 默認的管理策略 --> <defaultCache eternal = "false" maxElementsInMemory = "10000" overflowToDisk = "true" diskPersistent = "false" timeToIdleSeconds = "120" timeToLiveSeconds = "120" diskExpiryThreadIntervalSeconds = "120" memoryStoreEvictionPolicy = "LRU"/> <!-- 此緩存最多能夠存活timeToLiveSeconds秒,若是期間超過timeToIdleSeconds秒未訪問,緩存失效 --> <cache name = "userCache" eternal = "false" maxElementsInMemory = "100" overflowToDisk = "false" diskPersistent = "false" timeToIdleSeconds = "120" timeToLiveSeconds = "180" memoryStoreEvictionPolicy = "LRU"/> <!-- maxElementsInMemory 內存中最大緩存對象數,看着本身的heap大小來搞 --> <!-- eternal:true表示對象永不過時,此時會忽略timeToIdleSeconds和timeToLiveSeconds屬性,默認爲false --> <!-- maxElementsOnDisk:硬盤中最大緩存對象數,如果0表示無窮大 --> <!-- overflowToDisk:true表示當內存緩存的對象數目達到了maxElementsInMemory界限後, 會把溢出的對象寫到硬盤緩存中。注意:若是緩存的對象要寫入到硬盤中的話,則該對象必須實現了Serializable接口才行。--> <!-- diskSpoolBufferSizeMB:磁盤緩存區大小,默認爲30MB。每一個Cache都應該有本身的一個緩存區。--> <!-- diskPersistent:是否緩存虛擬機重啓期數據 --> <!-- diskExpiryThreadIntervalSeconds:磁盤失效線程運行時間間隔,默認爲120秒 --> <!-- timeToIdleSeconds: 設定容許對象處於空閒狀態的最長時間,以秒爲單位。當對象自從最近一次被訪問後, 若是處於空閒狀態的時間超過了timeToIdleSeconds屬性值,這個對象就會過時, EHCache將把它從緩存中清空。只有當eternal屬性爲false,該屬性纔有效。若是該屬性值爲0, 則表示對象能夠無限期地處於空閒狀態 --> <!-- timeToLiveSeconds:設定對象容許存在於緩存中的最長時間,以秒爲單位。當對象自從被存放到緩存中後, 若是處於緩存中的時間超過了 timeToLiveSeconds屬性值,這個對象就會過時, EHCache將把它從緩存中清除。只有當eternal屬性爲false,該屬性纔有效。若是該屬性值爲0, 則表示對象能夠無限期地存在於緩存中。timeToLiveSeconds必須大於timeToIdleSeconds屬性,纔有意義 --> <!-- memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時, Ehcache將會根據指定的策略去清理內存。可選策略有:LRU(最近最少使用,默認策略)、 FIFO(先進先出)、LFU(最少訪問次數)。--> </ehcache>