在spring boot项目中使用缓存很方便,有如下两种使用场景:

  1. 直接操作RedisTemplate缓存数据
  2. 在方法上加@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;}
}

说明:

  1. 在class上面需要加上@EnableCaching与@EnableScheduling注解
  2. 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缓存数据与自动清除相关推荐

  1. Spring Boot集成Redis缓存之模拟高并发场景处理

    前言 同样我们以上一篇文章为例子,搭建好环境之后,我欧美可以模拟高并发场景下,我们的缓存效率怎么样,到底能不能解决我们实际项目中的缓存问题.也就是如何解决缓存穿透? Spring Boot集成Redi ...

  2. Spring boot - 整合 Redis缓存(上)

    一.配置Pom文件 在使用spring boot 2.0整合redis时遇到了好多问题,网上很多例子都是1.x版本的.故2.0没有折腾好所以将2.0降到了1.5.降级后由于thymeleaf版本也会从 ...

  3. Spring Boot 集成 Redis 缓存

    Spring Boot 集成 Redis 缓存 在此章,我们将 SpringBoot 集成 Redis 缓存,Redis是一个开源的,基于内存的数据结构存储,可以用作数据库.缓存和消息代理,在本章仅讲 ...

  4. Spring Boot 结合 Redis 缓存

    Redis官网: 中:http://www.redis.cn/ 外:https://redis.io/ redis下载和安装 Redis官方并没有提供Redis的Windows版本,这里使用微软提供的 ...

  5. Spring Boot集成Redis缓存之RedisTemplate的方式

    前言 Spring Boot 集成Redis,将自动配置 RedisTemplate,在需要使用的类中注入RedisTemplate的bean即可使用 @Autowired private Redis ...

  6. Spring Boot整合Redis缓存(Lettuce)

    spring-boot-demo-cache-redis 此 demo 主要演示了 Spring Boot 如何整合 redis,操作redis中的数据,并使用redis缓存数据.连接池使用 Lett ...

  7. Spring Boot基础学习笔记18:Spring Boot整合Redis缓存实现

    文章目录 零.学习目标 一.Spring Boot支持的缓存组件 二.基于注解的Redis缓存实现 (一)安装与启动Redis (二)创建Spring Boot项目 - RedisCacheDemo0 ...

  8. Spring Boot集成Redis缓存之注解方式

    首先还是加入依赖Jar pom.xml中加入依赖 <!-- 加载spring boot redis 包 --><dependency><groupId>org.sp ...

  9. Spring boot - 整合 Redis缓存(下)

    在SpringBoot项目中使用Redis进行缓存接口返回数据,以及结合课程表的增删查改进行获取更新缓存. 一.相关注解 @Cacheable.@CachePut.@CacheEvict 在Sprin ...

最新文章

  1. 集合框架一:Collection集合
  2. 现代谱估计:Blackman-Tukey 相关图
  3. 二:unittest框架配合selenium之xpath定位
  4. [BZOJ2326] [HNOI2011] 数学作业 (矩阵乘法)
  5. 11 个 Linux 上最佳的图形化 Git 客户端
  6. mysql in partition_MySQL Partition分区扫盲
  7. python opencv findcontours_OpenCV之视频分析 – 背景消除与前景ROI提取
  8. 46 - 算法 -Leetcode 168 -位运算 类型模拟倒序利用vector
  9. 简明 Vim 练级攻(转自coolshell)
  10. 什么是MongoDB
  11. OC @class关键字
  12. 在Win2000和XP中更换身份不必非要注销
  13. 用于文本去重(相似度计算)的Simhash算法学习及python实现(持续学习中)
  14. 湖南启动CCTV《星光达人秀》 《宾导会客厅》全球直播发布
  15. 投资组合分析的 GE McKinsey 矩阵
  16. JCA - 核心类和接口 - Cipher类
  17. Linux安装Kibana详细教程
  18. iOS 中如何识别图片清晰度
  19. 基本概念学习(十)---系统
  20. Sentinel_LDK linux加密使用

热门文章

  1. angular使ng-zorro的nz-tree树控件
  2. Fastadmin JS
  3. AR增强现实如何影响对数据中心的变革?|AR机房
  4. matlab离散线性时不变系统的分析,实验3线性时不变系统的时域分析及matlab实现.doc...
  5. js获取当前日期时间以及获取过去一年和半年时间以及其它操作(有示例代码)
  6. VM15 安装 MacOS
  7. 技术演讲培训干货分享:三大要点,14个tips
  8. 2021最新最全!IntelliJ Idea如何使用使用Git!Git到底是什么!(值得一看)
  9. 八、Python3自动化运维——质量报表模块
  10. 第十三章 欧拉图与哈密顿图(图论)