用慣了 Redis ,很多人已經忘記了還有另一個快取方案 Ehcache ,是的,在 Redis 一統江湖的時代,Ehcache 漸漸有點沒落了,不過,我們還是有必要了解下 Ehcache ,在有的場景下,我們還是會用到 Ehcache。
今天鬆哥就來和大家聊聊 Spring Boot 中使用 Ehcache 的情況。相信看完本文,大家對於[Spring Boot 操作 Redis,三種方案全解析!]一文中的第二種方案會有更加深刻的理解。
Ehcache 也是 Java 領域比較優秀的快取方案之一,Ehcache 這個快取的名字很有意思,正著念反著念,都是 Ehcache,Spring Boot 中對此也提供了很好的支援,這個支援主要是通過 Spring Cache 來實現的。
Spring Cache 可以整合 Redis,當然也可以整合 Ehcache,兩種快取方案的整合還是比較相似,主要是配置的差異,具體的用法是一模一樣的,就類似於 JDBC 和 資料庫驅動的關係一樣。前面配置完成後,後面具體使用的 API 都是一樣的。
和 Spring Cache + Redis 相比,Spring Cache + Ehcache 主要是配置有所差異,具體的用法是一模一樣的。我們來看下使用步驟。
專案建立
首先,來建立一個 Spring Boot 專案,引入 Cache 依賴:
工程建立完成後,引入 Ehcache 的依賴,Ehcache 目前有兩個版本:
這裡採用第二個,在 pom.xml 檔案中,引入 Ehcache 依賴:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.6</version>
</dependency>
</dependencies>
新增 Ehcache 配置
在 resources 目錄下,新增 ehcache 的配置檔案 ehcache.xml ,檔案內容如下:
<ehcache>
<diskStore path="java.io.tmpdir/shiro-spring-sample"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
<cache name="user"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="true"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="600"/>
</ehcache>
配置含義:
- name:快取名稱。
- maxElementsInMemory:快取最大個數。
- eternal:物件是否永久有效,一但設定了,timeout將不起作用。
- timeToIdleSeconds:設定物件在失效前的允許閒置時間(單位:秒)。僅當eternal=false物件不是永久有效時使用,可選屬性,預設值是0,也就是可閒置時間無窮大。
- timeToLiveSeconds:設定物件在失效前允許存活時間(單位:秒)。最大時間介於建立時間和失效時間之間。僅當eternal=false物件不是永久有效時使用,預設是0.,也就是物件存活時間無窮大。
- overflowToDisk:當記憶體中物件數量達到maxElementsInMemory時,Ehcache將會物件寫到磁碟中。
- diskSpoolBufferSizeMB:這個引數設定DiskStore(磁碟快取)的快取區大小。預設是30MB。每個Cache都應該有自己的一個緩衝區。
- maxElementsOnDisk:硬碟最大快取個數。
- diskPersistent:是否快取虛擬機器重啟期資料。
- diskExpiryThreadIntervalSeconds:磁碟失效執行緒執行時間間隔,預設是120秒。
- memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理記憶體。預設策略是LRU(最近最少使用)。你可以設定為FIFO(先進先出)或是LFU(較少使用)。
- clearOnFlush:記憶體數量最大時是否清除。
- diskStore 則表示臨時快取的硬碟目錄。
注意
預設情況下,這個檔名是固定的,必須叫 ehcache.xml ,如果一定要換一個名字,那麼需要在 application.properties 中明確指定配置檔名,配置方式如下:
spring.cache.ehcache.config=classpath:aaa.xml
開啟快取
開啟快取的方式,也和 Redis 中一樣,如下新增 @EnableCaching
依賴即可:
@SpringBootApplication
@EnableCaching
public class EhcacheApplication {
public static void main(String[] args) {
SpringApplication.run(EhcacheApplication.class, args);
}
}
其實到這一步,Ehcache 就算配置完成了,接下來的用法,和鬆哥之前講 Redis 的文章一模一樣。不過這裡鬆哥還是帶大家使用下。
使用快取
這裡主要向小夥伴們介紹快取中幾個核心的註解使用。
@CacheConfig
這個註解在類上使用,用來描述該類中所有方法使用的快取名稱,當然也可以不使用該註解,直接在具體的快取註解上配置名稱,示例程式碼如下:
@Service
@CacheConfig(cacheNames = "user")
public class UserService {
}
@Cacheable
這個註解一般加在查詢方法上,表示將一個方法的返回值快取起來,預設情況下,快取的 key 就是方法的引數,快取的 value 就是方法的返回值。示例程式碼如下:
@Cacheable(key = "#id")
public User getUserById(Integer id,String username) {
System.out.println("getUserById");
return getUserFromDBById(id);
}
當有多個引數時,預設就使用多個引數來做 key ,如果只需要其中某一個引數做 key ,則可以在 @Cacheable 註解中,通過 key 屬性來指定 key ,如上程式碼就表示只使用 id 作為快取的 key ,如果對 key 有複雜的要求,可以自定義 keyGenerator 。當然,Spring Cache 中提供了root物件,可以在不定義 keyGenerator 的情況下實現一些複雜的效果,root 物件有如下屬性:
也可以通過 keyGenerator 自定義 key ,方式如下:
@Component
public class MyKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
return method.getName()+Arrays.toString(params);
}
}
然後在方法上使用該 keyGenerator :
@Cacheable(keyGenerator = "myKeyGenerator")
public User getUserById(Long id) {
User user = new User();
user.setId(id);
user.setUsername("lisi");
System.out.println(user);
return user;
}
@CachePut
這個註解一般加在更新方法上,當資料庫中的資料更新後,快取中的資料也要跟著更新,使用該註解,可以將方法的返回值自動更新到已經存在的 key 上,示例程式碼如下:
@CachePut(key = "#user.id")
public User updateUserById(User user) {
return user;
}
@CacheEvict
這個註解一般加在刪除方法上,當資料庫中的資料刪除後,相關的快取資料也要自動清除,該註解在使用的時候也可以配置按照某種條件刪除( condition 屬性)或者或者配置清除所有快取( allEntries 屬性),示例程式碼如下:
@CacheEvict()
public void deleteUserById(Integer id) {
//在這裡執行刪除操作, 刪除是去資料庫中刪除
}
總結
本文主要向大家了 Spring Boot 整合 Ehcache 的用法,其實說白了還是 Spring Cache 的用法。相信讀完本文,大家對於 Redis + Spring Cache 的用法會有更深的認識。
本文案例我已上傳到 GitHub ,歡迎大家 star:https://github.com/lenve/javaboy-code-samples
關於本文,有問題歡迎留言討論。
關注公眾號牧碼小子,專注於 Spring Boot+微服務以及前後端分離等全棧技術,定期視訊教程分享,關注後回覆 Java ,領取鬆哥為你精心準備的 Java 乾貨!