當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
spring boot 缓存_SpringBoot 应用 Redis 声明式缓存
生活随笔
收集整理的這篇文章主要介紹了
spring boot 缓存_SpringBoot 应用 Redis 声明式缓存
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
什么是聲明式緩存 ?
Spring 框架提供一種抽象的緩存機制,且 Spring 只提供接口,不提供緩存的具體實現。所以在程序中使用時,需要有具體緩存的實現。目前支持的常見的緩存比如 JDK ConcurrentMap-based Cache、Ehcache、Redis、Caffeine Cache、Guava Cache 等。
所謂聲明式緩存,即使用 Spring 框架提供的注解來使用緩存功能。這就需要知道一些常用的注解:
- @EnableCaching
Spring 默認沒有開啟緩存注解支持,可以在配置類上使用該注解進行開啟。
- @Cacheable
程序在執行方法時首先會去緩存中檢查 key 對應的 value 是否存在。如果存在,則方法體不再執行,直接取緩存中的 value 返回;否則執行方法體,并將方法的返回值進行緩存。@Cacheable 注解的使用傾向于減少方法的執行。
- @CachePut
方法執行完畢之后,將返回值 update 或者 insert 到緩存中。
- @CacheEvict
方法執行完畢之后,將緩存刪除。
更多關于 Spring 框架緩存注解的說明可以參考官方文檔:Spring Boot Caching
測試環境說明
- SpringBoot版本:2.0.2.RELEASE
- Redis 版本:3.2.9,pom 依賴:
- MySQL 版本:8.0.12,pom 依賴:
- mock 數據 sql:
測試代碼
代碼中已經給出了詳細的注釋說明,且使用方法也比較簡單,不做過多解釋。
Redis 配置
/*** <h1>Redis 配置</h1>* 繼承 CachingConfigurerSupport 重寫 CacheManager 和 KeyGenerator* Created by Qinyi.*/ @EnableCaching // 啟用緩存功能, 默認不啟用 @Configuration public class RedisConfig extends CachingConfigurerSupport {private final RedisConnectionFactory redisConnectionFactory;@Autowiredpublic RedisConfig(RedisConnectionFactory redisConnectionFactory) {this.redisConnectionFactory = redisConnectionFactory;}/*** <h2>配置 CacheManager: 序列化方式、過期時間</h2>* */@Overridepublic CacheManager cacheManager() {// 初始化一個 RedisCacheWriter// RedisCacheWriter 提供了對 Redis 的 set、setnx、get 等命令的訪問權限// 可以由多個緩存實現共享,并負責寫/讀來自 Redis 的二進制數據RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);// 設置 CacheManager 的值序列化方式RedisSerializer<Object> jsonSerializer = new JdkSerializationRedisSerializer();RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer);// 提供 Redis 的配置RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);// 設置默認超過期時間是 30 秒defaultCacheConfig.entryTtl(Duration.ofSeconds(30));// 初始化 RedisCacheManager 返回return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);}/*** <h2>定義 key 生成器: 類名、方法名、參數列表</h2>* 自定義 KeyGenerator 的核心思想是保證 key 不會沖突* 默認的是 SimpleKeyGenerator, 它使用方法參數組合生成的一個 key, 這里存在一個問題:* 如果2個方法, 參數是一樣的. 但執行邏輯不同, 那么將會導致執行第二個方法時命中第一個方法的緩存. 所以, 通常需要自定義.* */@Overridepublic KeyGenerator keyGenerator() {return (clazz, method, args) -> {StringBuilder sb = new StringBuilder();sb.append(clazz.getClass().getName()).append("#");sb.append(method.getName()).append("(");for (Object obj : args) {sb.append(obj.toString()).append(",");}sb.deleteCharAt(sb.length() - 1);sb.append(")");return sb.toString();};} }城市信息實體
/*** <h1>城市信息實體</h1>* Created by Qinyi.*/ @Data @NoArgsConstructor @AllArgsConstructor @Entity @Table(name = "city_info") public class CityInfo implements Serializable {/** 自增主鍵 */@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id", nullable = false)private Long id;/** 城市名稱 */@Basic@Column(name = "city", nullable = false)private String city;/** 經度 */@Basic@Column(name = "longitude", nullable = false)private Long longitude;/** 緯度 */@Basic@Column(name = "latitude", nullable = false)private Long latitude; }城市信息服務接口定義
/*** <h1>城市信息服務接口定義</h1>* Created by Qinyi.*/ public interface ICityInfoService {/*** <h2>根據 id 獲取城市信息</h2>* @param id 記錄 id* @return {@link CityInfo}* */CityInfo getCityInfoById(Long id);/*** <h2>更新城市信息</h2>* @param newObj 新的城市信息* @return {@link CityInfo}* */CityInfo updateCityInfo(CityInfo newObj);/*** <h2>根據 id 刪除城市信息</h2>* @param id 記錄 id* */void deleteCityInfoById(Long id); }城市信息服務接口定義
/*** <h1>城市信息服務接口定義</h1>* Created by Qinyi.*/ @Slf4j @Service public class CityInfoServiceImpl implements ICityInfoService {/** CityInfo Dao */private final CityInfoRepository repository;@Autowiredpublic CityInfoServiceImpl(CityInfoRepository repository) {this.repository = repository;}/*** <h2>根據 id 獲取城市信息</h2>* 如果不指定 key, 則會使用 KeyGenerator 來生成 key* 1. 如果指定了 key = "#id", redis 中的 key 是 city_info::1* 2. 如果使用自定義的 KeyGenerator(不指定 key), redis 中的 key 是:* city_info::com.imooc.ad.service.impl.CityInfoServiceImpl#getCityInfoById(1)* */@Override@SuppressWarnings("all")@Cacheable(cacheNames = "city_info", key = "#id") // @Cacheable(cacheNames = "city_info")public CityInfo getCityInfoById(Long id) {log.info("get CityInfo by id: {}", id.toString());return repository.findById(id).get();}@Override@CachePut(cacheNames="city_info", key="#newObj.id")public CityInfo updateCityInfo(CityInfo newObj) {log.info("update CityInfo: {}", JSON.toJSONString(newObj));return repository.save(newObj);}@Override@CacheEvict(cacheNames = "city_info", key = "#id")public void deleteCityInfoById(Long id) {log.info("delete CityInfo by id: {}", id.toString());repository.deleteById(id);} }Spring 聲明式緩存測試用例
/*** <h1>Spring 聲明式緩存測試用例</h1>* Created by Qinyi.*/ @RunWith(SpringRunner.class) @SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.NONE) public class CacheAnnotationTest {@Autowiredprivate ICityInfoService cityInfoService;/*** <h2>測試多次獲取, 可以直接從緩存(Redis)中獲取數據, 而不用查詢數據庫</h2>* */@Testpublic void testGetCityInfoById() {System.out.println(JSON.toJSONString(cityInfoService.getCityInfoById(1L)));}/*** <h2>測試更新緩存</h2>* */@Testpublic void testUpdateCityInfo() {System.out.println(JSON.toJSONString(cityInfoService.updateCityInfo(new CityInfo(1L, "合肥", 11717L, 3153L))));}/*** <h2>測試刪除緩存</h2>* */@Testpublic void testDeleteCityInfoById() {cityInfoService.deleteCityInfoById(1L);} }執行測試用例之后,可以在 Redis 中看到自動生成的緩存 KV:
127.0.0.1:6379> keys * 1) "city_info::1" 2) "city_info::com.imooc.ad.service.impl.CityInfoServiceImpl#getCityInfoById(1)" 127.0.0.1:6379> type city_info::1 string 127.0.0.1:6379> get city_info::1 "xacxedx00x05srx00x1ccom.imooc.ad.entity.CityInfoxe2/O>xd3xe6xeexc8x02x00x04Lx00x04citytx00x12Ljava/lang/String;Lx00x02idtx00x10Ljava/lang/Long;Lx00blatitudeqx00~x00x02Lx00tlongitudeqx00~x00x02xptx00x06xe5x90x88xe8x82xa5srx00x0ejava.lang.Long;x8bxe4x90xccx8f#xdfx02x00x01Jx00x05valuexrx00x10java.lang.Numberx86xacx95x1dx0bx94xe0x8bx02x00x00xpx00x00x00x00x00x00x00x01sqx00~x00x05x00x00x00x00x00x00x0cPsqx00~x00x05x00x00x00x00x00x00-xc5" 12注:作者:張勤一
出處:http://www.imooc.com/article/283946
總結
以上是生活随笔為你收集整理的spring boot 缓存_SpringBoot 应用 Redis 声明式缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 线程状态_Java线程为何没有
- 下一篇: pytorch 模型可视化_PyTorc