SpringBoot學習筆記(6) SpringBoot資料快取Cache [Guava和Redis實現]
Spring定義了org.springframework.cache.CacheManager和org.springframework.cache.Cache介面來統一不同的快取技術,而SpringBoot為我們提供了自動配置多個CacheManager的實現
在不適用任何額外配置的情況下,預設使用SimpleCacheConfiguration
SpringBoot通過spring.cache為字首來配置快取
使用這些快取實現的話,只需匯入相關快取的依賴,並在配置類中使用@EnableCaching開啟快取即可
Guava實現
這裡簡單介紹下使用Guava實現
引入的依賴
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ibigsea</groupId> <artifactId>spirngboot-cache-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <boot.version>1.3.5.RELEASE</boot.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${boot.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>${boot.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> <version>${boot.version}</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>19.0</version> </dependency> </dependencies> </project>
dataCache.java
package com.ibigsea.springboot_cache_demo.cache; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import javax.annotation.PostConstruct; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; @Component public class DataCache { private Map<Long, String> dataMap = new HashMap<>(); /** * 初始化 */ @PostConstruct public void init() { dataMap.put(1L, "張三"); dataMap.put(2L, "李四"); dataMap.put(3L, "王五"); } /** * 查詢 * 如果資料沒有快取,那麼從dataMap裡面獲取,如果快取了, * 那麼從guavaDemo裡面獲取 * 並且將快取的資料存入到 guavaDemo裡面 * 其中key 為 #id+dataMap */ @Cacheable(value="guavaDemo" ,key="#id + 'dataMap'") public String query(Long id) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(sdf.format(new Date()) + " : query id is " + id); return dataMap.get(id); } /** * 插入 或者更新 * 插入或更新資料到dataMap中 * 並且快取到 guavaDemo中 * 如果存在了那麼更新快取中的值 * 其中key 為 #id+dataMap */ @CachePut(value="guavaDemo" ,key="#id + 'dataMap'") public String put(Long id, String value) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(sdf.format(new Date()) + " : add data ,id is "+ id); dataMap.put(id, value); // data persistence return value; } /** * 刪除 * 刪除dataMap裡面的資料 * 並且刪除快取guavaDemo中的資料 * 其中key 為 #id+dataMap */ @CacheEvict(value="guavaDemo" , key="#id + 'dataMap'") public void remove(Long id) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(sdf.format(new Date()) + " : remove id is "+ id + " data"); dataMap.remove(id); // data remove } }
關於快取註解中的value,就是配置檔案中的cache-names
關於註解中的key這個值,如果不指定的話 ,那麼會取方法引數當做Key
application.yml
spring:
cache:
#快取名稱
cache-names: guavaDemo
#快取最大數量500條, 快取失效時間 6個小時
guava.spec: maximumSize=500,expireAfterWrite=360m
App.java
package com.ibigsea.springboot_cache_demo;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ibigsea.springboot_cache_demo.cache.DataCache;
/**
* 是Spring Boot專案的核心註解,主要是開啟自動配置
*/
@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
@RestController
// 開啟快取
@EnableCaching
public class App {
@Autowired
private DataCache dataCache;
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@RequestMapping("/put")
public String put(Long id, String value) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(new Date()) + " : value is " + dataCache.put(id, value) ;
}
@RequestMapping("/get")
public String query(Long id){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(new Date()) + " : value is " +dataCache.query(id) ;
}
@RequestMapping("/remove")
public String remove(Long id) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dataCache.remove(id) ;
return sdf.format(new Date()) + " : success " ;
}
}
執行結果
關於註解配置:
@Cacheable
@CacheEvict
@CachePut
和上面的一樣,只是這個註解是用來更新或者插入資料到快取中的,
其中key自己定義,返回值會快取
還有就是SpringBoot會根據你的類路徑裡面的依賴jar,來確定使用什麼型別進行快取,所以基本是我們是不用配置spring.cache.type這個屬性的
Redis實現
Redis快取:
如果是用redis作為快取的話
我們只需要引入redis相關依賴,修改yml配置屬性
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ibigsea</groupId>
<artifactId>spirngboot-cache-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<boot.version>1.3.5.RELEASE</boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>${boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>${boot.version}</version>
</dependency>
<!-- <dependency> -->
<!-- <groupId>com.google.guava</groupId> -->
<!-- <artifactId>guava</artifactId> -->
<!-- <version>19.0</version> -->
<!-- </dependency> -->
</dependencies>
</project>
application.yml
spring:
cache:
#快取名稱
cache-names: guavaDemo
#快取最大數量500條, 快取失效時間 6個小時
#guava.spec: maximumSize=500,expireAfterWrite=360m
# REDIS (RedisProperties)
redis :
host : localhost # server host
port : 6379 # connection port
pool.max-idle : 8 # pool settings ...
pool.min-idle : 1
pool.max-active : 8
pool.max-wait : -1
就這樣就OK了,程式碼什麼的都是不用改變的,是不是很方便
測試結果
資料都會快取到redis裡面
其他的地方就不測試了 都是差不多的
使用其他實現匯入對應的依賴,然後新增配置即可
注意:
如果使用guava快取的時候 ,同時添加了redis的jar依賴,或者其他的依賴,可能會出現異常
這個時候加上 type: GUAVA 就可以