spring boot使用redis缓存数据与自动清除
在spring boot项目中使用缓存很方便,有如下两种使用场景:
- 直接操作RedisTemplate缓存数据
- 在方法上加@Cacheable注解来缓存数据
方法1适用于缓存session、token等用户登录信息
方法2适用于缓存查询结果
直接操作RedisTemplate能够很灵活的对存入缓存中的key与value做定制化、并能很容易的实现缓存对象的过期时间。用@Cacheable注解方式的话,是不支持设置TTL,也就是说没有直接的方式设置缓存对象的过期时间,那么怎样才能实现缓存对象的自动清除呢?别着急,接着看。
一、pom配置,要加入对spring-boot-starter-cache与spring-boot-starter-data-redis的依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.3.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- spring data redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.0</version></dependency><!-- spring data jpa--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!--jdbc pool --><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId><version>3.1.0</version></dependency><!-- jdbc driver --><dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.1.1</version></dependency><!-- auto redeploy <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency>--><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.32</version></dependency></dependencies>
二、写个RedisCacheConfig文件,扩展CachingConfigurerSupport。缓存的自动清除有cacheEvict方法注解实现。
@Configuration
@EnableCaching
@EnableScheduling
public class RedisCacheConfig extends CachingConfigurerSupport{private static final Logger logger = LoggerFactory.getLogger(RedisCacheConfig.class);@Resourceprivate LettuceConnectionFactory lettuceConnectionFactory;@Beanpublic KeyGenerator keyGenerator() {return new KeyGenerator() {@Overridepublic Object generate(Object target, Method method, Object... params) {StringBuffer sb = new StringBuffer();sb.append(target.getClass().getName());sb.append(method.getName());for (Object obj : params) {sb.append(obj.toString());}return sb.toString();}};}@Beanpublic CacheManager cacheManager(){RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory);@SuppressWarnings("serial")Set<String> cacheNames = new HashSet<String>() {{add("apiCache");add("dictDataCache");add("manufacturedGood");add("rawMaterial");}};builder.initialCacheNames(cacheNames);return builder.build();}@CacheEvict(allEntries = true, cacheNames = { "manufacturedGood", "rawMaterial"})@Scheduled(fixedDelay = 60*1000)public void cacheEvict() {logger.info("[RedisCacheConfig][cacheEvict] start to clear cache");}@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);om.enableDefaultTyping(DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();redisTemplate.setConnectionFactory(lettuceConnectionFactory);RedisSerializer<?> stringSerializer = new StringRedisSerializer();redisTemplate.setKeySerializer(stringSerializer);redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.setHashKeySerializer(stringSerializer);redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}
}
说明:
- 在class上面需要加上@EnableCaching与@EnableScheduling注解
- cacheEvict()方法就是实现缓存对象的自动清除的地方,@CacheEvict注解指明cacheNames中指定的缓存,allEntries = true表示清除每个缓存中的所有实体。@Scheduled指定以何种方式触发这个清除动作,fixedDelay = 60*1000 表明上次执行完毕后间隔1分钟清除一次。注意单位是毫秒。当然,还有其它的方式,比如fixedRate,cron等
三、通过@Cacheable自动缓存数据
@Service
public class RawMaterialQueryServiceImpl implements RawMaterialQueryService {@Autowiredprivate RawMaterialDao rawMaterialDao;@Override@Cacheable(cacheNames="rawMaterial",sync=true, key="'RawMaterialID'.concat(#p0)")public RawMaterial getById(Integer id) {if(null == id) {return null;}Optional<RawMaterial> optional = rawMaterialDao.findById(id);return optional.isPresent()?optional.get():null;}}
说明:
在getById这个方法上的@Cacheable注解对查询结果做缓存,将查询的结果缓存到rawMaterial中,key为固定前缀RawMaterialID加上查询参数id。sync=true,多线程用相同的id调用此方法,如果没有命中,只有一个线程会调用方法中的查询动作,其它线程会等待。
四、直接调用。写个辅助类,直接操作RedisTemplate。在put对象时,可以直接指定过期时间。
@Component
public class RedisUtil {private static final Logger logger = LoggerFactory.getLogger(RedisUtil.class);private static final String FRONT_END_SESSION_CACHE_PREFIX = "FE_SESS_";private static final String BACK_END_SESSION_CACHE_PREFIX = "BE_SESS_";private static final String LOCALE_CACHE_PREFIX = "LOCALE_";@Value("${cache.redis.defaultlocale}")private String defaultLocale;@Value("${cache.redis.session.backend.expiretime}")private int beSessionExpireTime;@Value("${cache.redis.session.frontend.expiretime}")private int feSessionExpireTime;@Resourceprivate RedisTemplate<Object, Object> redisTemplate;public void cacheFrontEndSession(String sessionId,Integer userId) {if(StringUtil.assertNull(sessionId)) {return;}putWithTimeout(FRONT_END_SESSION_CACHE_PREFIX+sessionId, userId,feSessionExpireTime);}public boolean removeFrontEndSession(String sessionId) {if(StringUtil.assertNull(sessionId)) {return true;}return delete(FRONT_END_SESSION_CACHE_PREFIX+sessionId);}public Integer getFrontEndSessionCache(String sessionId) {try {Object value = get(FRONT_END_SESSION_CACHE_PREFIX+sessionId);if(null != value) {putWithTimeout(FRONT_END_SESSION_CACHE_PREFIX+sessionId, value,feSessionExpireTime);return Integer.parseInt(value+"");}else {return null;}}catch(Exception e) {return null;}}public void cacheBackEndSession(String sessionId,Integer userId) {if(StringUtil.assertNull(sessionId)) {return;}putWithTimeout(BACK_END_SESSION_CACHE_PREFIX+sessionId, userId,beSessionExpireTime);}public boolean removeBackEndSession(String sessionId) {if(StringUtil.assertNull(sessionId)) {return true;}return delete(BACK_END_SESSION_CACHE_PREFIX+sessionId);}public Integer getBackEndSessionCache(String sessionId) {try {Object value = get(BACK_END_SESSION_CACHE_PREFIX+sessionId);if(null != value) {putWithTimeout(BACK_END_SESSION_CACHE_PREFIX+sessionId, value,beSessionExpireTime);return Integer.parseInt(value+"");}else {return null;}}catch(Exception e) {return null;}}public void cacheLocale(Integer userId,String locale) {if(null == userId) {return;}put(LOCALE_CACHE_PREFIX+userId, locale);}public String getLocaleCache(Integer userId) {try {return (String)get(LOCALE_CACHE_PREFIX+userId);}catch(Exception e) {return null;}}private void put(Object key,Object value) {redisTemplate.opsForValue().set(key, value);}private void putWithTimeout(Object key,Object value,long timeout) {redisTemplate.opsForValue().set(key, value,timeout,TimeUnit.SECONDS);}private Object get(Object key) {if(null == key) {return null;}return redisTemplate.opsForValue().get(key);}private boolean delete(Object key) {if(null == key) {return true;}return redisTemplate.delete(key);}public String getDefaultLocale() {return defaultLocale;}}
五、配置文件application.properties
#=====================redis config================================
spring.cache.type=redis
spring.redis.host=192.168.1.252
spring.redis.port=6379
spring.redis.password=xxxxx
spring.redis.database=0
spring.redis.timeout=5000
spring.redis.lettuce.pool.max-idle=50
spring.redis.lettuce.pool.min-idle=10
spring.redis.lettuce.pool.max-active=-1
spring.redis.lettuce.pool.max-wait=-1
cache.redis.defaultlocale=zh_CN
#session过期时间,单位:秒
cache.redis.session.backend.expiretime=300
cache.redis.session.frontend.expiretime=3600
总结, 通过上述步骤,展示了在spring boot项目中同时使用通过操作RedisTemplate和@Cacheable的方式来缓存数据,并实现缓存的自动清除功能。
spring boot使用redis缓存数据与自动清除相关推荐
- Spring Boot集成Redis缓存之模拟高并发场景处理
前言 同样我们以上一篇文章为例子,搭建好环境之后,我欧美可以模拟高并发场景下,我们的缓存效率怎么样,到底能不能解决我们实际项目中的缓存问题.也就是如何解决缓存穿透? Spring Boot集成Redi ...
- Spring boot - 整合 Redis缓存(上)
一.配置Pom文件 在使用spring boot 2.0整合redis时遇到了好多问题,网上很多例子都是1.x版本的.故2.0没有折腾好所以将2.0降到了1.5.降级后由于thymeleaf版本也会从 ...
- Spring Boot 集成 Redis 缓存
Spring Boot 集成 Redis 缓存 在此章,我们将 SpringBoot 集成 Redis 缓存,Redis是一个开源的,基于内存的数据结构存储,可以用作数据库.缓存和消息代理,在本章仅讲 ...
- Spring Boot 结合 Redis 缓存
Redis官网: 中:http://www.redis.cn/ 外:https://redis.io/ redis下载和安装 Redis官方并没有提供Redis的Windows版本,这里使用微软提供的 ...
- Spring Boot集成Redis缓存之RedisTemplate的方式
前言 Spring Boot 集成Redis,将自动配置 RedisTemplate,在需要使用的类中注入RedisTemplate的bean即可使用 @Autowired private Redis ...
- Spring Boot整合Redis缓存(Lettuce)
spring-boot-demo-cache-redis 此 demo 主要演示了 Spring Boot 如何整合 redis,操作redis中的数据,并使用redis缓存数据.连接池使用 Lett ...
- Spring Boot基础学习笔记18:Spring Boot整合Redis缓存实现
文章目录 零.学习目标 一.Spring Boot支持的缓存组件 二.基于注解的Redis缓存实现 (一)安装与启动Redis (二)创建Spring Boot项目 - RedisCacheDemo0 ...
- Spring Boot集成Redis缓存之注解方式
首先还是加入依赖Jar pom.xml中加入依赖 <!-- 加载spring boot redis 包 --><dependency><groupId>org.sp ...
- Spring boot - 整合 Redis缓存(下)
在SpringBoot项目中使用Redis进行缓存接口返回数据,以及结合课程表的增删查改进行获取更新缓存. 一.相关注解 @Cacheable.@CachePut.@CacheEvict 在Sprin ...
最新文章
- 集合框架一:Collection集合
- 现代谱估计:Blackman-Tukey 相关图
- 二:unittest框架配合selenium之xpath定位
- [BZOJ2326] [HNOI2011] 数学作业 (矩阵乘法)
- 11 个 Linux 上最佳的图形化 Git 客户端
- mysql in partition_MySQL Partition分区扫盲
- python opencv findcontours_OpenCV之视频分析 – 背景消除与前景ROI提取
- 46 - 算法 -Leetcode 168 -位运算 类型模拟倒序利用vector
- 简明 Vim 练级攻(转自coolshell)
- 什么是MongoDB
- OC @class关键字
- 在Win2000和XP中更换身份不必非要注销
- 用于文本去重(相似度计算)的Simhash算法学习及python实现(持续学习中)
- 湖南启动CCTV《星光达人秀》 《宾导会客厅》全球直播发布
- 投资组合分析的 GE McKinsey 矩阵
- JCA - 核心类和接口 - Cipher类
- Linux安装Kibana详细教程
- iOS 中如何识别图片清晰度
- 基本概念学习(十)---系统
- Sentinel_LDK linux加密使用
热门文章
- angular使ng-zorro的nz-tree树控件
- Fastadmin JS
- AR增强现实如何影响对数据中心的变革?|AR机房
- matlab离散线性时不变系统的分析,实验3线性时不变系统的时域分析及matlab实现.doc...
- js获取当前日期时间以及获取过去一年和半年时间以及其它操作(有示例代码)
- VM15 安装 MacOS
- 技术演讲培训干货分享:三大要点,14个tips
- 2021最新最全!IntelliJ Idea如何使用使用Git!Git到底是什么!(值得一看)
- 八、Python3自动化运维——质量报表模块
- 第十三章 欧拉图与哈密顿图(图论)