• 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实战派-第十一章

  • 相关阅读:
    CURL常用命令
    极客无极限 一行HTML5代码引发的创意大爆炸
    JS的prototype和__proto__(含es6的class)
    leetcode 44:construct-binary-tree-from-preorder-and-inorder
    leetcode 43:construct-binary-tree-from-inorder-and-postorder
    leetcode 42:binary-tree-level-order-traversal-ii
    leetcode 38:path-sum
    leetcode 37:path-sum-ii
    leetcode 33:pascals-triangle
    leetcode 32:pascals-triangle-ii
  • 原文地址:https://www.cnblogs.com/weixia-blog/p/14194962.html
Copyright © 2020-2023  润新知