• spring整合SpringCache


    安装

      <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-cacheartifactId>
      dependency>
    
    • 1
    • 2
    • 3
    • 4

    yml

    spring:
      redis:
        port: 6379
        host: 192.168.182.130
      cache:
        type: redis
        redis:
          time-to-live: 3600000   #1 hourse
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    配置config

    @EnableConfigurationProperties(CacheProperties.class)
    @Configuration
    @EnableCaching
    public class MyRedisCacheConfig {
        @Bean
        RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
            RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
    //        config = config.entryTtl(Duration.ofHours(1));
            //key解析成string
            config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer(StandardCharsets.UTF_8)));
            //value解析成json
            config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
            CacheProperties.Redis redisProperties = cacheProperties.getRedis();
            if (redisProperties.getTimeToLive() != null) {
                config = config.entryTtl(redisProperties.getTimeToLive());
            }
            if (redisProperties.getKeyPrefix() != null) {
                config = config.prefixKeysWith(redisProperties.getKeyPrefix());
            }
            if (!redisProperties.isCacheNullValues()) {
                config = config.disableCachingNullValues();
            }
            if (!redisProperties.isUseKeyPrefix()) {
                config = config.disableKeyPrefix();
            }
            return config;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    配置config2,一般用上面的,编译出错再用下面的

    @EnableCaching //开启缓存
    @Configuration  //配置类
    @EnableConfigurationProperties(CacheProperties.class)
    public class RedisConfig extends CachingConfigurerSupport {
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            template.setConnectionFactory(factory);
            //key序列化方式
            template.setKeySerializer(redisSerializer);
            //value序列化
            template.setValueSerializer(jackson2JsonRedisSerializer);
            //value hashmap序列化
            template.setHashValueSerializer(jackson2JsonRedisSerializer);
            return template;
        }
    
        @Bean
        public CacheManager cacheManager(RedisConnectionFactory factory,CacheProperties cacheProperties) {
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            //解决查询缓存转换异常的问题
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            // 配置序列化(解决乱码的问题)
            RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
            //获取自定义yml
            CacheProperties.Redis propertiesRedis = cacheProperties.getRedis();
            if(propertiesRedis.getTimeToLive()!=null){
                config = config.entryTtl(propertiesRedis.getTimeToLive());
            }
            config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                    .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
            if(propertiesRedis.isCacheNullValues()){
                config = config.disableCachingNullValues();
            }
            RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                    .cacheDefaults(config)
                    .build();
    
            return cacheManager;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    应用

    allEntries = true是所有标记了缓存注解的方法都会根据当前的方法的注解删除缓存中对应的数据

    //删除缓存,失效模式
        @CacheEvict(value = "<你的缓存k>",allEntries = true)
        @Transactional
        @Override
         public void updateMethod(CategoryEntity category) {
    		//业务		
        }
    
    //存缓存
        @Cacheable(value = {"<你的缓存k>"},key = "#root.methodName")
        @Override
        public List<T> getMethod() {
    		//业务
    		return ...;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    默认行为

    1. 缓存存在,则方法不调用
    2. key默认自动生成,缓存名字::SimpleKey []
    3. 默认过期时间 ttl = -1
    4. 缓存的值,默认生成java序列化,序列化后存入到redis

    自定义行为

    1. 指定生成缓存使用的key
    2. 指定设置缓存数据的存活时间 yml:spring.cache.redis.time-to-live=?
    3. 将数据保存为json格式,方便其他接口兼容 自定义MyRedisCacheConfig

    spring-Cache的不足问题

    读模式

    1. 缓存穿透:查询一个null值。解决:缓存空数据:配置ymlcache-null-values: true
    2. 缓存击穿(解决本地锁问题):大量并发进来同时查询一个正好过期的数据。解决:加锁,默认是无加锁,可以@Cacheable(value = "",sync = true)
    3. 缓存雪崩:大量key同时过期,解决加随机时间,ymltime-to-live: 3600000 #1小时

    写模式

    1. 读写加锁
    2. 引入Canal,感知到MySql的更新去更新数据库
    3. 读多写多,直接去数据库查就可以了

    总结

    常规数据,完全可以用使用spring-cache
    特殊数据,另外设计

  • 相关阅读:
    分享!JetBrains IDE中的GitLab支持
    微信扫码关注公众号登录功能php实战分享
    bugku-web-文件上传
    docker run -v 用户目录的权限配置
    每天5分钟快速玩转机器学习算法:带有核函数的支持向量机模型
    LeetCode 1408. 数组中的字符串匹配
    程序员VS产品经理的世纪之争
    JTS: 15 Angle 角度计算
    读博准备路线图
    暴力破解常见服务学习
  • 原文地址:https://blog.csdn.net/weixin_45031570/article/details/126129328