天天看點

Spring Boot2 整合 Ehcache

用慣了 Redis ,很多人已經忘記了還有另一個緩存方案 Ehcache ,是的,在 Redis 一統江湖的時代,Ehcache 漸漸有點沒落了,不過,我們還是有必要了解下 Ehcache ,在有的場景下,我們還是會用到 Ehcache。

今天gblfy就來和大家聊聊 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 和web依賴:

Spring Boot2 整合 Ehcache

工程建立完成後,引入 Ehcache 的依賴,Ehcache 目前有兩個版本:

Spring Boot2 整合 Ehcache

這裡采用第二個,在 pom.xml 檔案中,引入 Ehcache 依賴:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.10.6</version>
        </dependency>      

添加 Ehcache 配置

在 resources 目錄下,添加 ehcache 的配置檔案 ehcache.xml ,檔案内容如下:

<ehcache>
    <diskStore path="java.io.tmpdir/springboot-sample"/>
    <!--
    diskStore:表示緩存持久化的檔案夾

    下面定義的不同cache 節點屬于不同的緩存政策

    name:緩存名稱。
       maxElementsInMemory:緩存最大個數。
       eternal:對象是否永久有效,一但設定了,timeout将不起作用。
       timeToIdleSeconds:設定對象在失效前的允許閑置時間(機關:秒)。僅當eternal=false對象不是永久有效時使用,可選屬性,預設值是0,也就是可閑置時間無窮大。
       timeToLiveSeconds:設定對象在失效前允許存活時間(機關:秒)。最大時間介于建立時間和失效時間之間。僅當eternal=false對象不是永久有效時使用,預設是0.,也就是對象存活時間無窮大。
       overflowToDisk:當記憶體中對象數量達到maxElementsInMemory時,Ehcache将會對象寫到磁盤中。
       diskSpoolBufferSizeMB:這個參數設定DiskStore(磁盤緩存)的緩存區大小。預設是30MB。每個Cache都應該有自己的一個緩沖區。
       maxElementsOnDisk:硬碟最大緩存個數。
       diskPersistent:是否緩存虛拟機重新開機期資料 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
       diskExpiryThreadIntervalSeconds:磁盤失效線程運作時間間隔,預設是120秒。
       memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache将會根據指定的政策去清理記憶體。預設政策是LRU(最近最少使用)。你可以設定為FIFO(先進先出)或是LFU(較少使用)。
       clearOnFlush:記憶體數量最大時是否清除。

    -->
    <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>      

注意

預設情況下,這個檔案名是固定的,必須叫 ehcache.xml ,如果一定要換一個名字,那麼需要在 application.properties 中明确指定配置檔案名,配置方式如下:

#spring.cache.ehcache.config=classpath:aaa.xml
      

開啟緩存

開啟緩存的方式,也和 Redis 中一樣,如下添加 @EnableCaching 依賴即可:

@SpringBootApplication
@EnableCaching
public class Springboot2EhcacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springboot2EhcacheApplication.class, args);
    }

}      

其實到這一步,Ehcache 就算配置完成了,接下來的用法,和松哥之前講 Redis 的文章一模一樣。不過這裡gblfy還是帶大家使用下。

這裡主要向小夥伴們介紹緩存中幾個核心的注解使用。

@CacheConfig

這個注解在類上使用,用來描述該類中所有方法使用的緩存名稱,當然也可以不使用該注解,直接在具體的緩存注解上配置名稱,示例代碼如下:

@Service
@CacheConfig(cacheNames = "user")
public class HelloService {}      

@Cacheable

這個注解一般加在查詢方法上,表示将一個方法的傳回值緩存起來,預設情況下,緩存的 key 就是方法的參數,緩存的 value 就是方法的傳回值。示例代碼如下:

@Cacheable(key = "#id")
    public User getUserById(long id, String name) {
        System.out.println("getUserById");
        return getUserFromDBById(id);
    }      

當有多個參數時,預設就使用多個參數來做 key ,如果隻需要其中某一個參數做 key ,則可以在 @Cacheable 注解中,通過 key 屬性來指定 key ,如上代碼就表示隻使用 id 作為緩存的 key ,如果對 key 有複雜的要求,可以自定義 keyGenerator 。當然,Spring Cache 中提供了root對象,可以在不定義 keyGenerator 的情況下實作一些複雜的效果,root 對象有如下屬性:

Spring Boot2 整合 Ehcache

也可以通過 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().builder()
                .id(id)
                .name("gblfy")
                .build();
        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(long id){
    //    在這裡執行删除操作,删除就是去資料庫中删除
    }      

繼續閱讀