SpringBoot(11)——使用SpringCache
使用Spring Cache
Spring提供了Cache抽象,它允許我們宣告哪些bean的哪些方法的外部呼叫需要使用Cache。方法呼叫使用了Cache後,在呼叫真實方法前會先從快取中獲取結果,快取中如果沒有則會呼叫真實方法,這也是基於AOP實現的。關於Spring Cache的介紹不是本文的重點,如有需要可以參考筆者寫的http://elim.iteye.com/blog/2123030。
在Spring Boot應用中使用Spring Cache需要在@SpringBootConfiguration
標註的Class上新增@EnableCaching
,這樣就啟用了Spring Cache。Spring Boot將根據Classpath下提供的Spring Cache實現類選擇合適的實現者進行自動配置,支援的實現有基於Ehcache的實現、基於Redis的實現等,詳情可參考org.springframework.boot.autoconfigure.cache.CacheConfiguration
的原始碼。如果沒有找到,則會使用基於ConcurrentMap的實現。
下面的程式碼中就啟用了Spring Cache。
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setAddCommandLineProperties(false);
app.run(args);
}
}
然後就可以在bean中使用Spring Cache提供的註解進行快取的定義了,下面的程式碼中就定義了getTime()
將使用名稱為cacheName1
的快取。
@Component
public class SimpleService {
@Cacheable("cacheName1")
public long getTime() {
return System.currentTimeMillis();
}
}
簡單的驗證快取生效的單元測試如下。
@SpringBootTest(classes=Application.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class CacheTest {
@Autowired
private SimpleService simpleService;
@Test
public void testGetTime() throws Exception {
long time1 = this.simpleService.getTime();
TimeUnit.MILLISECONDS.sleep(100);
long time2 = this.simpleService.getTime();
Assert.assertEquals(time1, time2);
}
}
使用Ehcache實現
需要使用Spring Cache的Ehcache實現,首先需要在pom.xml中加入如下依賴。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
然後最簡單的方式是在Classpath的根路徑下放一個ehcache.xml
檔案,這樣Spring Boot預設就會啟用Spring Cache的Ehcache實現了。Ehcache的自動配置由EhCacheCacheConfiguration
定義。如果Ehcache的配置檔案不是存放在Classpath根路徑,則可以通過spring.cache.ehcache.config
來指定,比如下面的程式碼指定了在Classpath下的config目錄下尋找ehcache.xml檔案作為Ehcache的配置檔案。
spring.cache.ehcache.config=classpath:/config/ehcache.xml
Spring Cache的自動配置的屬性定義類是CacheProperties,參考其API文件或原始碼可以檢視選擇的Spring Cache的實現可以指定的詳細的配置資訊。
SimpleService的getTime()
指定了使用的Cache是名稱為cacheName1的Cache。所以在ehcache.xml中需要定義一個名為cacheName1的Cache,配置如下:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
maxBytesLocalHeap="100M">
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120"
maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap" />
</defaultCache>
<cache name="cacheName1" />
</ehcache>
如果應用中應用了很多不同名稱的Cache,如果都把它們在ehcache.xml中定義一次,可能你會覺得太麻煩。可能你想把一些主要的Cache在ehcache.xml中定義,進行充分的自定義配置。然後其它的則能夠在使用的時候自動建立,並使用預設的預設的快取配置,則可以定義自己的EhCacheCacheManager實現bean,實現getMissingCache()
的邏輯為不存在則建立。這樣Spring Boot將不再自動建立EhCacheCacheManager bean。下面的程式碼是一個簡單的示例。
@Component
public class MyEhCacheCacheManager extends EhCacheCacheManager {
@Override
protected Cache getMissingCache(String name) {
Cache cache = super.getMissingCache(name);
if (cache == null) {
Ehcache ehcache = super.getCacheManager().addCacheIfAbsent(name);
cache = new EhCacheCache(ehcache);
}
return cache;
}
}
使用Redis實現
需要使用Redis實現需要在pom.xml中新增spring-boot-starter-data-redis
依賴,這樣Spring Boot將自動建立RedisTemplate bean,有了RedisTemplate bean後Spring Boot將自動建立基於Redis實現的Spring Cache的CacheManager,RedisCacheManager。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Spring Boot預設建立的RedisTemplate將使用localhost作為服務地址,埠號是6379,資料庫索引為0,可以通過spring.redis.host
指定Redis服務IP,spring.redis.port
指定Redis服務監聽埠號,spring.redis.database
指定需要使用的資料庫索引號。下面的程式碼中就指定了使用的是10.10.10.3
這臺主機上的Redis,資料庫索引號是1。關於Redis的更多配置資訊可以參考org.springframework.boot.autoconfigure.data.redis.RedisProperties
的API文件。
spring.redis.host=10.10.10.3
spring.redis.database=1
預設Spring Cache的Redis實現存入Redis中的Key是cacheName::cacheKey
的形式,其中cacheName是當前Spring Cache的name,cacheKey是Spring Cache傳遞過來的Key。可以通過spring.cache.redis.key-prefix
指定存入Redis中的Key的字首,當指定了該屬性時,生成的Key將是該字首加上Spring Cache傳遞過來的Key。比如下面的程式碼中指定了字首是test-spring-cache::
,如果Spring Cache傳遞的Key是key1,則最終存入Redis中的Key將是test-spring-cache::key1
。
spring.cache.redis.key-prefix=test-spring-cache::
可以通過spring.cache.redis.timeToLive
指定Redis快取的Key的存活時間。下面的程式碼中就指定了快取的有效時間是60秒。
spring.cache.redis.timeToLive=60s
關於Spring Cache的Redis實現的更多配置可以參考org.springframework.boot.autoconfigure.cache.CacheProperties.Redis
的API文件。
指定Cache實現
當Classpath下同時存放了多個Spring Cache的實現類,並且同時有多個Spring Cache實現類可以滿足啟用條件時,Spring Boot將按照一定的順序進行選擇,一旦應用了某個型別的Spring Cache實現後,其它型別的Spring Cache實現將是非啟用的,因為這些自動啟用的前提都要求當前環境中尚未有Spring Cache的CacheManager型別的bean。自動啟用的順序是按照org.springframework.boot.autoconfigure.cache.CacheType
這個列舉中定義的順序來的,它的定義如下。
/**
* Generic caching using `Cache` beans from the context.
*/
GENERIC,
/**
* JCache (JSR-107) backed caching.
*/
JCACHE,
/**
* EhCache backed caching.
*/
EHCACHE,
/**
* Hazelcast backed caching.
*/
HAZELCAST,
/**
* Infinispan backed caching.
*/
INFINISPAN,
/**
* Couchbase backed caching.
*/
COUCHBASE,
/**
* Redis backed caching.
*/
REDIS,
/**
* Caffeine backed caching.
*/
CAFFEINE,
/**
* Simple in-memory caching.
*/
SIMPLE,
/**
* No caching.
*/
NONE
所以一旦Classpath下同時擁有Ehcache和Redis的Spring Cache實現時,將優先使用Ehcache的實現,如果想使用Redis的實現,可以通過spring.cache.type=redis
指定使用Redis的實現。
指定Cache實現僅針對於自動配置生效,如果是自己定義了CacheManager實現,則該配置無效。
CacheManagerCustomizer
CacheManagerCustomizer是用來對CacheManager進行自定義擴充套件的,其定義如下:
@FunctionalInterface
public interface CacheManagerCustomizer<T extends CacheManager> {
/**
* Customize the cache manager.
* @param cacheManager the {@code CacheManager} to customize
*/
void customize(T cacheManager);
}
當需要對某個CacheManager實現進行一些自定義時,可以實現CacheManagerCustomizer介面,指定泛型為需要進行自定義的CacheManager實現類,然後把它定義為一個Spring bean。下面的程式碼就對Ehcache實現的CacheManager進行了一些自定義,其在EhCacheCacheManager初始化後採用預設的Cache配置建立了一些Cache。
@Component
public class EhcacheCacheManagerCustomizer implements CacheManagerCustomizer<EhCacheCacheManager> {
@Override
public void customize(EhCacheCacheManager cacheManager) {
List<String> cacheNames = Arrays.asList("cacheName1", "cacheName2", "cacheName3", "cacheName4", "cacheName5", "cacheName6");
cacheNames.forEach(cacheManager.getCacheManager()::addCacheIfAbsent);
}
}
關於Spring Cache的自動配置可以參考org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
的原始碼或API文件。
(注:本文是基於Spring Boot 2.0.3所寫)
相關文章
- Springboot 整合 SpringCache 使用 Redis 作為快取Spring BootGCRedis快取
- 優雅的快取解決方案--SpringCache和Redis整合(SpringBoot)快取GCRedisSpring Boot
- 一篇掌握SpringBoot+SpringCache+Redis超詳細例項Spring BootGCRedis
- 分散式鎖結合SpringCache分散式SpringGC
- SpringCache框架載入/攔截原理SpringGC框架
- 學習springBoot(11)shiro安全框架Spring Boot框架
- SpringBoot-11 擴充套件功能Spring Boot套件
- SpringBoot之:SpringBoot中使用HATEOASSpring Boot
- springboot開發淺談 2021/05/11Spring Boot
- SpringBoot使用JdbcTemplateSpring BootJDBC
- SpringBoot使用LomBokSpring BootLombok
- SpringBoot使用JPASpring Boot
- SpringBoot使用WebSocketSpring BootWeb
- springboot 使用 rocketMQSpring BootMQ
- SpringBoot使用RedisSpring BootRedis
- SpringBoot使用WebJarsSpring BootWebJAR
- SpringBoot使用AOPSpring Boot
- SpringBoot(17)——使用SpringDataJPASpring Boot
- SpringBoot AOP的使用Spring Boot
- SpringBoot使用外部tomcatSpring BootTomcat
- SpringBoot(14)——使用WebClientSpring BootWebclient
- springboot 使用mustcache模板Spring Boot
- SpringBoot使用快取Spring Boot快取
- SpringBoot 使用 Redis GeoSpring BootRedis
- springboot + activeMQ基本使用Spring BootMQ
- springboot整合使用JdbcTemplateSpring BootJDBC
- _005_SpringBoot_使用IDEA建立SpringBoot專案Spring BootIdea
- 2020-11-14springboot學習筆記03Spring Boot筆記
- SpringBoot 中使用 JDBC TempletSpring BootJDBC
- SpringBoot使用prometheus監控Spring BootPrometheus
- SpringBoot使用Nacos配置中心Spring Boot
- 註解@PropertySource使用 springbootSpring Boot
- SpringBoot使用validator校驗Spring Boot
- SpringBoot使用Mybatis-PageHelperSpring BootMyBatis
- SpringBoot 中 JPA 的使用Spring Boot
- springboot中RedisTemplate的使用Spring BootRedis
- 在SpringBoot中使用SpringSecuritySpring BootGse
- SpringBoot的@Conditional使用 - reflectoringSpring Boot