赞
踩
在Spring-boot集成Redis基础上,集成spring-cache
Spring-boot集成Redis
1、RedisConfig 类添加注解 @EnableCaching
2、keyGenerator
/** * 自定义缓存的key * @return */ @Bean @Override public KeyGenerator keyGenerator() { return new KeyGenerator(){ @Override public Object generate(Object target, Method method, Object... params){ StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()).append("."); sb.append(method.getName()).append("."); for (Object obj : params) { sb.append(obj.toString()); } System.out.println("keyGenerator="+sb.toString()); return sb.toString(); } }; }
3、cacheManager
/** * 创建RedisCacheManager * @param connectionFactory * @return */ @Bean public CacheManager cacheManager(RedisConnectionFactory connectionFactory){ //初始化一个RedisCacheWriter RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory); //设置CacheManager的值序列化方式 //RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair); RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig(); //设置默认超过期时间是30秒 defaultCacheConfig.entryTtl(Duration.ofSeconds(30)); //初始化RedisCacheManager RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig); return redisCacheManager; }
4、方法中添加注解
/** * 保存缓存 * @param id * @return */ @Cacheable(value = "log", key = "'log'.concat(#id.toString())") public Log findLogById(Long id) { String sql = "select id,content,createtime from log_info where id = ?"; RowMapper<Log> rowMapper = new BeanPropertyRowMapper<>(Log.class); Log log = jdbcTemplate.queryForObject(sql,rowMapper,id); System.out.println("log="+log); return log; } /** * 重新保存缓存 * @param log * @return */ @CachePut(value = "log", key = "'log'.concat(#log.id.toString())") public Log update(Log log) { Integer id = log.getId(); String content = "测试缓存"+id; log.setContent(content); jdbcTemplate.update("UPDATE log_info SET content = ? WHERE id = ?", new Object[] {content, id}); System.out.println("log="+log); return log; } /** * 删除缓存 * @param id */ @CacheEvict(value = "log", key = "'log'.concat(#id.toString())") public void remove(Long id) { String sql = "delete from log_info where id=?"; int update = jdbcTemplate.update(sql, id); System.out.println(update); }
5、注解描述
@Cacheable 触发缓存入口 一般用于查询操作,根据key查询缓存. 1. 如果key不存在,查询db,并将结果更新到缓存中。 2. 如果key存在,直接查询缓存中的数据。 @CacheEvict 触发移出缓存 根据key删除缓存中的数据。allEntries=true表示删除缓存中的所有数据。 @CachePut 触发更新缓存 一般用于更新和插入操作,每次都会请求db 1. 如果key存在,更新内容 2. 如果key不存在,插入内容。 @Caching 将多种缓存操作分组 这个注解将其他注解方式融合在一起了,我们可以根据需求来自定义注解,并将前面三个注解应用在一起 @CacheConfig 类级别的缓存注解,允许共享缓存名称 该注解是可以将缓存分类,它是类级别的注解方式。
6、自定义AOP缓存
自定义注解
/**
* 元注解 用来标识查询数据库的方法
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisCache {
}
自定义Aspect
/** * AOP实现Redis缓存处理 */ @Component @Aspect public class RedisAspect { @Autowired private RedisService redisService; /** * 拦截所有元注解RedisCache注解的方法 */ @Pointcut("@annotation(com.seata.business.annotation.RedisCache)") public void pointcutMethod(){ } /** * 环绕处理,先从Redis里获取缓存,查询不到,就查询MySQL数据库, * 然后再保存到Redis缓存里 * @param joinPoint * @return */ @Around("pointcutMethod()") public Object around(ProceedingJoinPoint joinPoint){ //前置:从Redis里获取缓存 //先获取目标方法参数 long startTime = System.currentTimeMillis(); String applId = null; Object[] args = joinPoint.getArgs(); if (args != null && args.length > 0) { applId = String.valueOf(args[0]); } //获取目标方法所在类 String target = joinPoint.getTarget().toString(); String className = target.split("@")[0]; //获取目标方法的方法名称 String methodName = joinPoint.getSignature().getName(); //redis中key格式: applId:方法名称 String redisKey = applId + ":" + className + "." + methodName; Object obj = redisService.getCacheObject(redisKey); if(obj!=null){ System.out.println("**********从Redis中查到了数据**********"); System.out.println("Redis的KEY值:"+redisKey); System.out.println("Redis的VALUE值:"+obj.toString()); return obj; } long endTime = System.currentTimeMillis(); System.out.println("Redis缓存AOP处理所用时间:"+(endTime-startTime)); System.out.println("**********没有从Redis查到数据**********"); try{ obj = joinPoint.proceed(); }catch(Throwable e){ e.printStackTrace(); } System.out.println("**********开始从MySQL查询数据**********"); //后置:将数据库查到的数据保存到Redis redisService.setCacheObject(redisKey,obj); if(redisService.hasKey(redisKey)){ System.out.println("**********数据成功保存到Redis缓存!!!**********"); System.out.println("Redis的KEY值:"+redisKey); System.out.println("Redis的VALUE值:"+obj.toString()); } return obj; } /** * 增删改操作会先将对应的缓存从redis中删除 * 再重新查询数据库并重新存入redis缓存 * @param joinPoint */ @After("execution(* com.seata.business.service.*.*(..)) && !execution(* com.seata.business.service.*.select*(..))&& !execution(* com.seata.business.service.*.find*(..))") public void after(JoinPoint joinPoint){ String name = joinPoint.getTarget().getClass().getName(); redisService.deleteObject(name); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。