Spring boot詳解緩存redis實(shí)現(xiàn)定時(shí)過(guò)期方法
前言
使用redis進(jìn)行緩存數(shù)據(jù),是目前比較常用的緩存解決方案。常用的緩存形式有一下幾種:
1.純?cè)a進(jìn)行redis的增刪改查,手工編寫(xiě)緩存工具類,由開(kāi)發(fā)者在代碼中進(jìn)行調(diào)用。
優(yōu)勢(shì):代碼由實(shí)際使用的開(kāi)發(fā)者進(jìn)行維護(hù),便于定制化的改造。
2.使用市場(chǎng)上已有的緩存工具,也就是大家常說(shuō)的大佬的輪子
優(yōu)勢(shì):方便快捷,提升開(kāi)發(fā)效率
添加依賴
修改pom文件引入如下配置
<?xml version="1.0" encoding="UTF-8"?> <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.test</groupId> <artifactId>common-project</artifactId> <version>0.0.1-SNAPSHOT</version> <name>common-project</name> <description></description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.7</version> </dependency> </dependencies> </project>
添加配置
application.yml中增加redisd 配置信息
spring:
redis:
host: localhost
port: 6379
database: 0
password: *****
timeout: 10000
server:
port: 8082
常規(guī)緩存
在spring 3.1版本以后,注意是spring的版本,不是spring boot的版本。在spring-context包中合并進(jìn)去了spring Cache的內(nèi)容??梢允褂米⒔夥绞竭M(jìn)行緩存設(shè)定。
開(kāi)啟緩存
開(kāi)啟緩存只需要在入口函數(shù)上增加@EnableCaching注解
@SpringBootApplication @EnableCaching //開(kāi)啟緩存 public class CommonApplication { public static void main(String[] args) { SpringApplication.run(CommonApplication.class,args); } }
設(shè)置緩存空間
設(shè)置緩存空間可能大家不好理解,換一個(gè)通俗的說(shuō)法就是設(shè)置要緩存的類,把這個(gè)類下面要緩存的數(shù)據(jù)的key加上一個(gè)統(tǒng)一的前綴,也是一個(gè)注解:@CacheConfig這里可以設(shè)置具體的值如下
@RestController @RequestMapping("/test") @CacheConfig(cacheNames = "test-controller") public class TestController { @Autowired TestService testService; @RequestMapping("/testCache") @Cacheable(key = "'testCache'",unless = "#result==null") public Object testCache(){ return testService.getUserInfoList(); } }
這里的cacheNames就是我上面說(shuō)的緩存空間,也許這樣還是沒(méi)辦法理解,請(qǐng)看在redis中的緩存情況:
就是說(shuō)如果我在TestController類下設(shè)置的接口緩存數(shù)據(jù)都會(huì)緩存到test-controller這個(gè)緩存空間里。
設(shè)置緩存
這里就是指具體要緩存的接口數(shù)據(jù),使用注解:@Cacheable,具體代碼參見(jiàn)上面的代碼塊。
截止到這里,就可以啟動(dòng)服務(wù),調(diào)用接口,會(huì)發(fā)現(xiàn)數(shù)據(jù)已經(jīng)可以緩存到redis中了。但是,這里有一個(gè)問(wèn)題,就是緩存下來(lái)的數(shù)據(jù),是永久緩存,一旦接口實(shí)際的數(shù)據(jù)有更新,只能通過(guò)再設(shè)置更新方法來(lái)更新緩存,或者刪除緩存,我們都知道redis本身是支持設(shè)置key的過(guò)期時(shí)間的,這一特性,讓緩存變得更加優(yōu)雅,所以我們的程序也要有?。?!
增加設(shè)置緩存過(guò)期時(shí)間
想要設(shè)置緩存過(guò)期時(shí)間,也并不是很麻煩,只是需要單獨(dú)增加一個(gè)redis的配置類,自定義修改一下緩存管理器就可以了
@Configuration public class RedisCacheManagerConfig { /** * redis模板配置以及序列化配置 * * @param factory 工廠 * @return {@link RedisTemplate}<{@link String}, {@link Object}> */ @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); //key 采用的String 的序列化方式 template.setKeySerializer(stringRedisSerializer); //hashde key 也采用String的序列化方式 template.setHashKeySerializer(stringRedisSerializer); //value 序列化方式采用jackson template.setValueSerializer(jackson2JsonRedisSerializer); //hash 的 value序列化方式采用jackson template.setHashKeySerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); template.afterPropertiesSet(); return template; } @Bean RedisCacheWriter writer(RedisTemplate<String, Object> redisTemplate) { return RedisCacheWriter.nonLockingRedisCacheWriter(Objects.requireNonNull(redisTemplate.getConnectionFactory())); } @Bean CacheManager cacheManager(RedisCacheWriter writer) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); Map<String, RedisCacheConfiguration> configurationMap = new HashMap<>(); // 配置序列化(解決亂碼的問(wèn)題) RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofHours(1))//time .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); //此處可以自定義緩存空間的緩存的過(guò)期時(shí)間,可以根據(jù)自己實(shí)際情況進(jìn)行設(shè)置,也可以不設(shè)置,用統(tǒng)一過(guò)期時(shí)間 configurationMap.put("test-controller", config.entryTtl(Duration.ofSeconds(200))); //解決查詢緩存轉(zhuǎn)換異常的問(wèn)題 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); return RedisCacheManager.builder(writer) .initialCacheNames(configurationMap.keySet()) .withInitialCacheConfigurations(configurationMap) //其他緩存空間緩存過(guò)期時(shí)間為500S .cacheDefaults(config.entryTtl(Duration.ofSeconds(500))) .build(); } }
增加了此配置類之后,之前的代碼均不需要更改,直接啟動(dòng)程序,測(cè)試驗(yàn)證,可以看到redis中的數(shù)據(jù)是被設(shè)置了過(guò)期時(shí)間的
此處可能會(huì)有個(gè)意外驚喜(小坑):就是直接啟動(dòng)程序后,調(diào)用接口報(bào)錯(cuò),提示json格式轉(zhuǎn)換異常,這里是由于先前直接用的默認(rèn)的redisTemplate,value的反序列化問(wèn)題,可以將之前緩存的數(shù)據(jù)清理一下,再重新調(diào)用就可以了。
總結(jié)
注解方式進(jìn)行接口數(shù)據(jù)緩存,在實(shí)際項(xiàng)目開(kāi)發(fā)過(guò)程中比較常見(jiàn),我分享的這種方式也是大家比較常用的一種方式,配置簡(jiǎn)單,開(kāi)發(fā)成本低,使用方便。只需要:
- 引入依賴包
- 增加redis連接信息
- 開(kāi)啟緩存
- 添加需要緩存的類或者方法
后記
這里題外記錄一下緩存注解中的一下參數(shù)含義及用法
另外設(shè)置緩存的注解中支持spEL表達(dá)式,下面是一些可用的表達(dá)式含義
到此這篇關(guān)于Spring boot詳解緩存redis實(shí)現(xiàn)定時(shí)過(guò)期方法的文章就介紹到這了,更多相關(guān)Spring boot定時(shí)過(guò)期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot整合阿里云OSS對(duì)象存儲(chǔ)服務(wù)實(shí)現(xiàn)文件上傳
這篇文章主要介紹了SpringBoot整合阿里云OSS對(duì)象存儲(chǔ)實(shí)現(xiàn)文件上傳,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot,感興趣的朋友可以了解下2021-04-04詳解Java字節(jié)碼編程之非常好用的javassist
這篇文章主要介紹了詳解Java字節(jié)碼編程之非常好用的javassist,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Java虛擬機(jī)JVM性能優(yōu)化(一):JVM知識(shí)總結(jié)
這篇文章主要介紹了Java虛擬機(jī)JVM性能優(yōu)化(一):JVM知識(shí)總結(jié),本文是系列文章的第一篇,后續(xù)篇章請(qǐng)繼續(xù)關(guān)注腳本之家,需要的朋友可以參考下2014-09-09Java創(chuàng)建多線程局域網(wǎng)聊天室實(shí)例
這篇文章主要介紹了Java創(chuàng)建多線程局域網(wǎng)聊天室實(shí)例,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07如何通過(guò)Java監(jiān)聽(tīng)MySQL數(shù)據(jù)的變化
對(duì)于二次開(kāi)發(fā)來(lái)說(shuō),很大一部分就找找文件和找數(shù)據(jù)庫(kù)的變化情況,下面這篇文章主要給大家介紹了關(guān)于如何通過(guò)Java監(jiān)聽(tīng)MySQL數(shù)據(jù)的變化的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03Spring?Boot中@Validated注解不生效問(wèn)題匯總大全
這篇文章主要給大家介紹了關(guān)于Spring?Boot中@Validated注解不生效問(wèn)題匯總的相關(guān)資料,@Validated注解是Spring框架中的一個(gè)注解,用于在方法參數(shù)上添加參數(shù)校驗(yàn)規(guī)則,需要的朋友可以參考下2023-07-07