當前位置: 華文問答 > 數碼

Java緩存技術常用的有哪些?

2016-03-14數碼

Java 緩存中介軟體

關鍵詞:Spring Cache、J2Cache、JetCache

一 、JSR 107

JSR107 中制訂了 Java 緩存的規範。

因此,在很多緩存框架、緩存庫中,其 API 都參考了 JSR 107 規範。

img

Java Caching 定義了 5 個核心介面

  • CachingProvider - 定義了建立、配置、獲取、管理和控制多個 CacheManager 。一個套用可以在執行期存取多個 CachingProvider
  • CacheManager - 定義了建立、配置、獲取、管理和控制多個唯一命名的 Cache,這些 Cache 存在於 CacheManager 的上下文中。一個 CacheManager 僅被一個 CachingProvider 所擁有。
  • Cache - 是一個類似 Map 的數據結構並臨時儲存以 Key 為索引的值。一個 Cache 僅被一個 CacheManager 所擁有。
  • Entry - 是一個儲存在 Cache 中的 key-value 對。
  • Expiry - 每一個儲存在 Cache 中的條目有一個定義的有效期,即 Expiry Duration。一旦超過這個時間,條目為過期的狀態。一旦過期,條目將不可存取、更新和刪除。緩存有效期可以透過 ExpiryPolicy 設定。
  • 二、Spring Cache

    詳見: Spring Cache 官方文件

    Spring 作為 Java 開發最著名的框架,也提供了緩存功能的框架—— Spring Cache。

    Spring 支持基於註釋(annotation)的緩存(cache)技術,它本質上不是一個具體的緩存實作方案(例如:EHCache 或 OSCache),而是一個對緩存使用的抽象,透過在既有程式碼中添加少量它定義的各種 annotation,即能夠達到緩存方法的返回物件的效果。

    Spring Cache 的特點:

  • 透過緩存註解即可支持緩存功能
  • 支持 Spring EL 運算式
  • 支持 AspectJ
  • 支持自訂 key 和緩存管理
  • 開啟緩存註解

    Spring 為緩存功能提供了註解功能,但是你必須啟動註解。

    有兩種方式:

    (一)使用標記註解 @EnableCaching

    這種方式對於 Spring 或 Spring Boot 專案都適用。

    @Configuration @EnableCaching public class AppConfig { }

    (二)在 xml 中聲明

    <cache:annotation-driven cache-manager="cacheManager"/>

    spring 緩存註解 API

    Spring 對緩存的支持類似於對事務的支持。

    首先使用註解標記方法,相當於定義了切點,然後使用 Aop 技術在這個方法的呼叫前、呼叫後獲取方法的入參和返回值,進而實作了緩存的邏輯。

    @Cacheable

    @Cacheable 用於觸發緩存

    表明所修飾的方法是可以緩存的:當第一次呼叫這個方法時,它的結果會被緩存下來,在緩存的有效時間內,以後存取這個方法都直接返回緩存結果,不再執行方法中的程式碼段。

    這個註解可以用 condition 內容來設定條件,如果不滿足條件,就不使用緩存能力,直接執行方法。

    可以使用 key 內容來指定 key 的生成規則。

    @CachePut

    @CachePut 用於更新緩存

    @Cacheable 不同, @CachePut 不僅會緩存方法的結果,還會執行方法的程式碼段。

    它支持的內容和用法都與 @Cacheable 一致。

    @CacheEvict

    @CacheEvict 用於清除緩存

    @Cacheable 功能相反, @CacheEvict 表明所修飾的方法是用來刪除失效或無用的緩存數據。

    下面是 @Cacheable @CacheEvict @CachePut 基本使用方法的一個集中展示:

    @Service public class UserService { // @Cacheable可以設定多個緩存,形式如:@Cacheable({"books", "isbns"}) @Cacheable(value={"users"}, key="#user.id") public User findUser(User user) { return findUserInDB(user.getId()); } @Cacheable(value = "users", condition = "#user.getId() <= 2") public User findUserInLimit(User user) { return findUserInDB(user.getId()); } @CachePut(value = "users", key = "#user.getId()") public void updateUser(User user) { updateUserInDB(user); } @CacheEvict(value = "users") public void removeUser(User user) { removeUserInDB(user.getId()); } @CacheEvict(value = "users", allEntries = true) public void clear() { removeAllInDB(); } }

    @Caching

    @Caching 用於組合定義多種緩存功能

    如果需要使用同一個緩存註解( @Cacheable @CacheEvict @CachePut )多次修飾一個方法,就需要用到 @Caching

    @Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") }) public Book importBooks(String deposit, Date date)

    @CacheConfig

    @CacheConfig 用於定義公共緩存配置

    與前面的緩存註解不同,這是一個類級別的註解。

    如果類的所有操作都是緩存操作,你可以使用 @CacheConfig 來指定類,省去一些配置。

    @CacheConfig("books") public class BookRepositoryImpl implements BookRepository { @Cacheable public Book findBook(ISBN isbn) {...} }

    三、Spring Boot Cache

    詳見: Spring Boot Cache 特性官方文件

    Spring Boot Cache 是在 Spring Cache 的基礎上做了封裝,使得使用更為便捷。

    Spring Boot Cache 快速入門

    (1)引入依賴

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <!-- 按序引入需要的緩存庫 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>

    (2)緩存配置

    例如,選用緩存為 redis,則需要配置 redis 相關的配置項(如:資料來源、連線池等配置資訊)

    # 緩存類別,支持類別:GENERIC、JCACHE、EHCACHE、HAZELCAST、INFINISPAN、COUCHBASE、REDIS、CAFFEINE、SIMPLE spring.cache.type = redis # 全域緩存時間 spring.cache.redis.time-to-live = 60s # Redis 配置 spring.redis.database = 0 spring.redis.host = localhost spring.redis.port = 6379 spring.redis.password =

    (3)使用 @EnableCaching 開啟緩存

    @EnableCaching @SpringBootApplication public class Application { // ... }

    (4)緩存註解( @Cacheable @CachePut @CacheEvit 等)使用方式與 Spring Cache 完全一樣

    四、JetCache

    JetCache 是一個基於 Java 的緩存系統封裝,提供統一的 API 和註解來簡化緩存的使用。 JetCache 提供了比 SpringCache 更加強大的註解,可以原生的支持 TTL、兩級緩存、分布式自動重新整理,還提供了 Cache 介面用於手工緩存操作。 當前有四個實作, RedisCache TairCache (此部份未在 github 開源)、 CaffeineCache (in memory)和一個簡易的 LinkedHashMapCache (in memory),要添加新的實作也是非常簡單的。
    詳見: jetcache Github

    jetcache 快速入門

    如果使用 Spring Boot,可以按如下的方式配置(這裏使用了 jedis 客戶端連線 redis,如果需要集群、讀寫分離、異步等特性支持請使用 lettuce 客戶端)。

    (1)引入 POM

    <dependency> <groupId>com.alicp.jetcache</groupId> <artifactId>jetcache-starter-redis</artifactId> <version>2.5.14</version> </dependency>

    (2)配置

    配置一個 spring boot 風格的 application.yml 檔,把他放到資源目錄中

    jetcache: statIntervalMinutes: 15 areaInCacheName: false local: default: type: linkedhashmap keyConvertor: fastjson remote: default: type: redis keyConvertor: fastjson valueEncoder: java valueDecoder: java poolConfig: minIdle: 5 maxIdle: 20 maxTotal: 50 host: 127.0.0.1 port: 6379

    (3)開啟緩存

    然後建立一個 App 類放在業務包的根下,EnableMethodCache,EnableCreateCacheAnnotation 這兩個註解分別啟用 Cached 和 CreateCache 註解,其他和標準的 Spring Boot 程式是一樣的。這個類可以直接 main 方法執行。

    package com.company.mypackage; import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation; import com.alicp.jetcache.anno.config.EnableMethodCache; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableMethodCache(basePackages = "com.company.mypackage") @EnableCreateCacheAnnotation public class MySpringBootApp { public static void main(String[] args) { SpringApplication.run(MySpringBootApp. class); } }

    (4)API 基本使用

    建立緩存例項

    透過 @CreateCache 註解建立一個緩存例項,預設超時時間是 100 秒

    @CreateCache(expire = 100) private Cache<Long, UserDO> userCache;

    用起來就像 map 一樣

    UserDO user = userCache.get(123L); userCache.put(123L, user); userCache.remove(123L);

    建立一個兩級(記憶體+遠端)的緩存,記憶體中的元素個數限制在 50 個。

    @CreateCache(name = "UserService.userCache", expire = 100, cacheType = CacheType.BOTH, localLimit = 50) private Cache<Long, UserDO> userCache;

    name 內容不是必須的,但是起個名字是個好習慣,展示統計數據的使用,會使用這個名字。如果同一個 area 兩個 @CreateCache 的 name 配置一樣,它們生成的 Cache 將指向同一個例項。

    建立方法緩存

    使用 @Cached 方法可以為一個方法添加上緩存。JetCache 透過 Spring AOP 生成代理,來支持緩存功能。註解可以加在介面方法上也可以加在類方法上,但需要保證是個 Spring bean。

    public interface UserService { @Cached(name="UserService.getUserById", expire = 3600) User getUserById(long userId); }

    五、j2cache

    六、總結

    使用緩存框架,使得開發緩存功能非常便捷。

    如果你的系統只需要使用一種緩存,那麽推薦使用 Spring Boot Cache。Spring Boot Cache 在 Spring Cache 基礎上做了封裝,使用更簡單、方便。

    如果你的系統需要使用多級緩存,那麽推薦使用 jetcache。

    參考資料

  • JSR107
  • Spring Cache 官方文件
  • Spring Boot Cache 特性官方文件
  • J2Cache Gitee
  • jetcache Github
  • jetcache wiki 選擇下載器: 下載此0條連結 當前處於選擇模式 點選/拖拽 滑鼠左鍵 選擇連結 點選/拖拽 滑鼠右鍵 取消選擇連結 按住 ALT鍵 點選/拖拽 滑鼠左鍵 取消選擇連結