目录
实现步骤
1. 在 pom.xml 配置文件中添加如下依赖
2. 在 application.properties 中添加如下配置
3. 新建 RedisConfig.class,继承 CachingConfigurerSupport,添加如下方法
4. 新建 RedisService.class 添加如下方法
注意:cacheKeyGenerator 是注入的 bean,实现类如下
5. 测试一下
注意
上一章已经介绍了如何在 SpringBoot 中如何使用缓存,本章将介绍如何将缓存和 Redis 结合使用
org.springframework.boot spring-boot-starter-data-redis
############################## redis 配置 ##############################
spring.redis.url = redis://localhost:6379
# 连接池最大活动连接数
spring.redis.lettuce.pool.max-active = 10
# 连接池中最小空闲连接数
spring.redis.lettuce.pool.min-idle = 5
# 最大连接等待时间
spring.redis.lettuce.pool.max-wait = 10ms
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {/*** RedisTemplate 序列化配置*/@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {RedisTemplate template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory);StringRedisSerializer keySerializer = new StringRedisSerializer();template.setKeySerializer(keySerializer);template.setHashKeySerializer(keySerializer);template.setValueSerializer(new GenericJackson2JsonRedisSerializer());template.afterPropertiesSet();return template;}/*** 注册缓存管理器*/@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {// 设置缓存 20 秒过期时间RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(20)).disableCachingNullValues();return RedisCacheManager.builder(factory).cacheDefaults(config).transactionAware().build();}
}
@Service
@CacheConfig(cacheNames={"test"}, keyGenerator="cacheKeyGenerator")
public class RedisService { // 该注解将向缓存中添加字符串 @Cacheable public String save1() { System.out.println(new Date() + " --> 没有从缓存取值"); return "ramos"; } // 该注解将向缓存中添加 user 对象 @Cacheable public User save2() { System.out.println(new Date() + " --> 没有从缓存取值"); return new User(1, "dufu"); } // 该注解将会向缓存中 添加/更新 新的值 // 与 @Cacheable 不同的是, 如下方法中的代码都会执行 @CachePut public String put(String value) { System.out.println(new Date() + " 添加了 value --> " + value); return value; } // 该注解将会把缓存中的值删除掉 // 与 @Cacheable 不同的是, 如下方法中的代码都会执行 @CacheEvict public void delete() { System.out.println(new Date() + " 删除了 value"); }
}
@Component
// 自定义缓存生成 key 的方式
public class CacheKeyGenerator implements KeyGenerator { // 将目标类的类名作为 key 值 @Override public Object generate(Object target, Method method, Object... params) { return target.getClass().getName() + method.getName(); }
}
这里明确了 key 的生成是 由类名 + 方法名 组成,因为如果设置 key 的值为固定值的话,有可能会出现转换错误,例如:假如 save1() 和 save2() 两个方法的返回值不一致,但是缓存的 key 值一样的话,可能会第一次调用 save1() 放入 { test: ramos } , 第二次调用 save2() 就会取出 Ramos(String),但是 save2() 的返回值类型是 User,这样就会出错
1. 自定义的实体类要被缓存,就必须实现 IO 的 Serializable 接口
@Data
public class User implements Serializable { private static final long serialVersionUI = 1L;private int id;private String name;
}
2. 集成缓存会与 SpringBoot 的热部署冲突,报错:class XX cannot be cast to class XX ,XX is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader
暂未找到两全其美的解决办法;只能注释掉热部署依赖
org.springframework.boot spring-boot-devtools true