引入依賴
<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實戰派-第十一章