SpringBoot配置Redis缓存

引入依赖

<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方法接受RedisCacheWriterRedisConnectionFactory类型的入参,返回RedisCacheManagerBuilder建造器,cacheDefaults方法指定缓存配置类,build方法生成RedisCacheManager实例

SpringBoot默认引入的RedisTemplateRedisTemplate<Object, Object>类型,默认使用JDK的序列化机制,会出现乱码,需要重写Redis配置

键(含Hash类型的键)使用StringRedisSerializer序列化,值(含Hash类型的值)使用GenericJackson2JsonRedisSerializer序列化

其他配置

  1. 入口类配置@EnableCaching
  2. 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);
    }
}

注意:

  1. 运行应用时,Redis服务器要处于运行状态
  2. 运行应用是,spring-boot-devtools热部署工具要停用

参考

Spring Boot 集成Spring Cache 和 Redis
[springboot配置redis缓存
SpringBoot实战派-第十一章

原文地址:https://www.cnblogs.com/weixia-blog/p/14194962.html