1. 程式人生 > >學習Springboot 快取

學習Springboot 快取

快取

Spring Framework支援透明地嚮應用程式新增快取。從本質上講,抽象將快取應用於方法,從而根據快取中可用的資訊減少執行次數。快取邏輯應用透明,不會對呼叫者造成任何干擾。只要通過@EnableCaching 註釋啟用了快取支援,Spring Boot就會自動配置快取基礎結構。摘譯自 官方文件

[注意]

有關更多詳細資訊,請檢視Spring Framework參考的相關部分

簡而言之,將快取新增到服務操作就像在其方法中新增相關注釋一樣簡單,如以下示例所示:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public class MathService {

	@Cacheable("piDecimals")
	public int computePiDecimal(int i) {
		// ...
	}

}

此示例演示瞭如何在可能代價高昂的操作上使用快取。在呼叫之前computePiDecimal,抽象會在piDecimals快取中查詢與i引數匹配的條目。如果找到條目,則快取中的內容會立即返回給呼叫者,並且不會呼叫該方法。否則,將呼叫該方法,並在返回值之前更新快取。

[警告] 警告

您還可以@CacheResult透明地使用標準JSR-107(JCache)註釋(例如 )。但是,我們強烈建議您不要混合使用Spring Cache和JCache註釋。

如果您不新增任何特定的快取庫,Spring Boot會自動配置一個在記憶體中使用併發對映的 

簡單提供程式。當需要快取時(例如piDecimals在前面的示例中),此提供程式會為您建立快取。簡單的提供程式並不是真正推薦用於生產用途,但它非常適合入門並確保您瞭解這些功能。當您決定使用快取提供程式時,請務必閱讀其文件以瞭解如何配置應用程式使用的快取。幾乎所有提供程式都要求您顯式配置在應用程式中使用的每個快取。有些提供了一種自定義spring.cache.cache-names屬性定義的預設快取的方法。

[小費]

還可以透明地 更新或 逐出快取中的資料。

支援的快取提供程式

快取抽象不提供實際儲存,而是依賴於org.springframework.cache.Cache

org.springframework.cache.CacheManager介面實現的抽象。

如果您尚未定義型別的bean CacheManagerCacheResolver命名 的bean cacheResolver(請參閱參考資料 CachingConfigurer),Spring Boot會嘗試檢測以下提供程式(按指示的順序):

  1. 通用
  2. JCache(JSR-107)(EhCache 3,Hazelcast,Infinispan等)
  3. EhCache 2.x
  4. Hazelcast
  5. Infinispan的
  6. Couchbase
  7. Redis的
  8. Caffeine
  9. 簡單
[小費]

也可以通過設定屬性來強制特定的快取提供程式 spring.cache.type。如果您需要在某些環境(例如測試)中完全禁用快取,請使用此屬性 。

[小費]

使用spring-boot-starter-cache“Starter”快速新增基本快取依賴項。首發引入spring-context-support。如果手動新增依賴項,則必須包括spring-context-support才能使用JCache,EhCache 2.x或Guava支援。

如果CacheManager由Spring Boot自動配置,則可以通過公開實現該CacheManagerCustomizer介面的bean完全初始化之前進一步調整其配置 。以下示例設定一個標誌,表示應將null值傳遞給底層對映:

@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
	return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
		@Override
		public void customize(ConcurrentMapCacheManager cacheManager) {
			cacheManager.setAllowNullValues(false);
		}
	};
}
[注意]

在前面的示例中,ConcurrentMapCacheManager預期會自動配置。如果不是這種情況(您提供了自己的配置或自動配置了不同的快取提供程式),則根本不會呼叫自定義程式。您可以擁有任意數量的自定義程式,也可以使用@Order或者訂購它們Ordered

通用

如果上下文定義至少一個 org.springframework.cache.Cachebean,則使用通用快取記憶體。將CacheManager建立包裝該型別的所有bean。

JCache(JSR-107)

JCache通過javax.cache.spi.CachingProvider類路徑上的存在(即類路徑上存在符合JSR-107的快取記憶體庫)進行自舉 ,JCacheCacheManager並由 spring-boot-starter-cache“Starter”提供。可以使用各種相容庫,Spring Boot為Ehcache 3,Hazelcast和Infinispan提供依賴管理。還可以新增任何其他相容庫。

可能會出現多個提供程式,在這種情況下必須明確指定提供程式。即使JSR-107標準沒有強制執行定義配置檔案位置的標準化方法,Spring Boot也會盡力滿足設定快取的實現細節,如下例所示:

#僅在存在多個提供程式時才需要

spring.cache.jcache.provider=com.acme.MyCachingProvider
spring.cache.jcache.config=classpath:acme.xml
[注意]

當快取庫同時提供本機實現和JSR-107支援時,Spring Boot更喜歡JSR-107支援,因此如果切換到不同的JSR-107實現,則可以使用相同的功能。

[小費]

Spring Boot 一般支援Hazelcast。如果單個HazelcastInstance可用,則CacheManager除非spring.cache.jcache.config指定了屬性,否則它也會自動重複使用 。

有兩種方法可以自定義底層javax.cache.cacheManager

  • 可以通過設定spring.cache.cache-names屬性在啟動時建立快取。如果定義了自定義javax.cache.configuration.Configurationbean,則會使用它來自定義它們。
  • org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer使用CacheManagerfor完全自定義的引用呼叫bean 。
[小費]

如果javax.cache.CacheManager定義了標準bean,它將自動包裝在org.springframework.cache.CacheManager抽象所期望的實現中。沒有進一步的自定義。

 EhCache 2.x

如果ehcache.xml可以在類路徑的根目錄中找到名為的檔案,則使用EhCache 2.x. 如果找到EhCache 2.x,則使用“Starter” EhCacheCacheManager提供的spring-boot-starter-cache引導快取管理器。還可以提供備用配置檔案,如以下示例所示:

spring.cache.ehcache.config=classpath:config/another-config.xml

Hazelcast

Spring Boot 一般支援Hazelcast。如果a HazelcastInstance已自動配置,則會自動包裝在a中CacheManager

Infinispan

Infinispan沒有預設配置檔案位置,因此必須明確指定。否則,使用預設載入程式。

spring.cache.infinispan.config=infinispan.xml

可以通過設定spring.cache.cache-names屬性在啟動時建立快取。如果定義了自定義ConfigurationBuilderbean,則它用於自定義快取。

[注意]

Infinispan在Spring Boot中的支援僅限於嵌入式模式,並且非常基礎。如果你想要更多選項,你應該使用官方的Infinispan Spring Boot啟動器。有關更多詳細資訊,請參閱 Infinispan的文件

Couchbase

如果Couchbase Java客戶端和couchbase-spring-cache 實現可用且配置了Couchbase ,CouchbaseCacheManager則會自動配置a。也可以通過設定spring.cache.cache-names屬性在啟動時建立其他快取。這些快取在Bucket自動配置的情況下執行。您可以建立另一個附加快取中Bucket,通過使用定製。假設您需要在“main” 和one()快取上使用兩個快取(cache1和 cache2),Bucketcache3在“另一個”上生成2秒的自定義時間Bucket。您可以通過配置建立前兩個快取,如下所示:

spring.cache.cache-names=cache1,cache2

然後,您可以定義一個@Configuration類來配置額外Bucket和 cache3快取,如下所示:

@Configuration
public class CouchbaseCacheConfiguration {

	private final Cluster cluster;

	public CouchbaseCacheConfiguration(Cluster cluster) {
		this.cluster = cluster;
	}

	@Bean
	public Bucket anotherBucket() {
		return this.cluster.openBucket("another", "secret");
	}

	@Bean
	public CacheManagerCustomizer<CouchbaseCacheManager> cacheManagerCustomizer() {
		return c -> {
			c.prepareCache("cache3", CacheBuilder.newInstance(anotherBucket())
					.withExpiration(2));
		};
	}

}

此示例配置重用Cluster通過自動配置建立的配置。

Redis

如果Redis可用並已配置,RedisCacheManager則會自動配置a。通過設定spring.cache.cache-names屬性可以在啟動時建立其他快取, 並且可以使用spring.cache.redis.*屬性配置快取預設值 。例如,以下配置建立 cache1cache2快取10分鐘的生存時間:

spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=600000
[注意]

預設情況下,會新增一個鍵字首,這樣,如果兩個單獨的快取使用相同的鍵,則Redis沒有重疊鍵,也不能返回無效值。如果您建立自己的設定,我們強烈建議您啟用此設定RedisCacheManager

[小費]

您可以通過新增RedisCacheConfiguration @Bean自己的配置來完全控制配置。如果您正在尋找自定義序列化策略,這可能很有用。

Caffeine

Caffeine是Java 8重寫的Guava快取,取代了對Guava的支援。如果存在咖啡因,則自動配置a CaffeineCacheManager(由spring-boot-starter-cache“Starter”提供)。可以通過設定spring.cache.cache-names屬性在啟動時建立快取,並可以通過以下之一(按指示的順序)自定義快取:

  1. 由...定義的快取規範 spring.cache.caffeine.spec
  2. com.github.benmanes.caffeine.cache.CaffeineSpec定義了一個bean
  3. com.github.benmanes.caffeine.cache.Caffeine定義了一個bean

例如,以下配置建立cache1cache2快取,最大大小為500,生存時間為 10分鐘

spring.cache.cache-names=cache1,cache2
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

如果com.github.benmanes.caffeine.cache.CacheLoader定義了bean,它將自動關聯到CaffeineCacheManager。由於CacheLoader它將與快取管理器管理的所有快取相關聯,因此必須將其定義為 CacheLoader<Object, Object>。自動配置忽略任何其他泛型型別。

簡單

如果找不到其他提供程式,ConcurrentHashMap則配置使用a 作為快取儲存的簡單實現 。如果您的應用程式中沒有快取庫,則這是預設值。預設情況下,會根據需要建立快取,但您可以通過設定cache-names屬性來限制可用快取的列表。例如,如果只需要cache1cache2快取,請cache-names按如下方式設定屬性:

spring.cache.cache-names=cache1,cache2

如果這樣做並且您的應用程式使用未列出的快取,則在需要快取時它會在執行時失敗,但在啟動時則不會。這類似於“真實”快取提供程式在使用未宣告的快取時的行為方式。

如果@EnableCaching配置中存在,則還需要合適的快取配置。如果需要在某些環境中完全禁用快取,請強制快取型別none使用no-op實現,如以下示例所示:

spring.cache.type=none