引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
不需要引入spring-boot-starter-cache
依赖
应用程序配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.cache.type=redis
编写Redis配置类
Redis缓存和RedisTemplate序列化时默认使用JDK序列化,在Redis客户端查看时会出现乱码,需要修改序列化方案
SpringBoot2.x开始,RedisCacheManager持有的RedisCacheWriter(负责操作Redis)不依赖RedisTemplate,这两个API需要分别修改序列化方案(用哪个API修改哪个,如果只是使用Redis缓存不需要修改RedisTemplate)
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
// 自定义key生成策略,按类名+方法名+参数名命名
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder key = new StringBuilder();
key.append(target.getClass().getName());
key.append(method.getName());
for (Object param : params) {
key.append(param.toString());
}
return key.toString();
}
};
}
// 缓存管理器
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
// 因为每步会生成新的对象,所以必须链式调用
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofDays(1))
// 设置序列化方式,否则客户端会呈现为二进制字符,value使用JSON序列化,key用String序列化
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.disableCachingNullValues();
// RedisCacheManager构造器需要两个参数:
// RedisCacheWriter, 负责操作redis,不依赖redisTemplate
// RedisCacheConfiguration, 设置redis缓存配置
// 创建无锁的RedisCacheWriter
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(factory);
return RedisCacheManager.builder(redisCacheWriter).cacheDefaults(redisCacheConfiguration).build();
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}
}
RedisCacheConfiguration
配置时,每调用一次方法会生成一个新的RedisCacheConfiguration
,所以必须链式调用
serializeKeysWith
方法需要SerializationPair
类型的入参,使用静态方法RedisSerializationContext.SerializationPair.fromSerializer
生成
RedisCacheManager
构造器需要两个参数:RedisCacheWriter
(负责操作Redis)和RedisCacheConfiguration
RedisCacheWriter.nonLockingRedisCacheWriter
静态方法创建无锁的RedisCacheWriter
RedisCacheManager.builder
方法接受RedisCacheWriter
或RedisConnectionFactory
类型的入参,返回RedisCacheManagerBuilder
建造器,cacheDefaults
方法指定缓存配置类,build
方法生成RedisCacheManager
实例
SpringBoot默认引入的RedisTemplate
是RedisTemplate<Object, Object>
类型,默认使用JDK的序列化机制,会出现乱码,需要重写Redis配置
键(含Hash类型的键)使用StringRedisSerializer
序列化,值(含Hash类型的值)使用GenericJackson2JsonRedisSerializer
序列化
其他配置
- 入口类配置@EnableCaching
- Service类添加缓存注解(@CacheConfig、@Cacheable、@CachePut、@CacheEvict)
- @CacheConfig标记在类上,统一配置缓存名
- @Cacheable,方法调用时先查询缓存,没有缓存从数据库加载数据
- @CachePut,先执行方法调用,方法执行完后把结果写入缓存
- @CacheEvict,方法调用完后把缓存清空
@Service
@CacheConfig(cacheNames = "book")
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
@CachePut(key = "#p0")
public void update(Book book) {
bookDao.save(book);
}
@CacheEvict(key ="#p0",allEntries=true)
public void delete(long id) {
bookDao.deleteById(id);
}
@Cacheable(key ="#p0")
public Book findById(long id) {
return bookDao.findById(id);
}
}
注意:
- 运行应用时,Redis服务器要处于运行状态
- 运行应用是,
spring-boot-devtools
热部署工具要停用
参考
Spring Boot 集成Spring Cache 和 Redis
[springboot配置redis缓存
SpringBoot实战派-第十一章