SpringCache 缓存注解

本文介绍如何使用Spring Boot整合Redis作为缓存,并通过Spring Cache注解实现缓存管理。包括依赖配置、自定义缓存管理器、注解使用及缓存问题解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

整合Springboot开发

第一步:加入相关依赖:

   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

第二步:写配置
(可以直接使用,只需要配置加入redis作为缓存,CacheAutoConfiguration-> RedisCachConfiguration->自动配置了RedisCacheManager->初始化所有的缓存->每个缓存决定使用什么配置->如果RedisCachConfiguration有就用己有的,没有就用默认配置->想修改缓存配置只需要给容器中放入一个RedisCachConfiguratio->就会应用到当前的RedisCacheManager管理的所有缓存分区中)

**自定义缓存管理器(将缓存保存为json格式),给容器中放入RedisCachConfiguratio **:

@EnableConfigurationProperties(CacheProperties.class)//将配置文件中的配置生效 
@Configuration
@EnableCaching
public class redisCacheConfiguration {


    @Bean
    RedisCacheConfiguration redisCacheConfigurationInit(CacheProperties cacheProperties) {
       //得到默认配置 
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();

        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()));
//配置JSON格式作为缓存数据
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
     
        //配置redis缓存格式
        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;
    }

}


application.properties

spring.cache.type=redis
spring.cache.redis.key-prefix=CACHE //指定缓存Key的前缀名,没指定就默认使用缓存名作为前缀
spring.cache.redis.use-key-prefix=true  //是否使用前缀
spring.cache.redis.cache-null-values=true //是否缓存空值,防止缓存穿透
spring.cache.redis.time-to-live=3600000 //设置缓存存活时间,时间单位毫秒


第三步开启缓存,@EnableCaching,主启动类开启缓存


@EnableCaching
@EnableFeignClients(basePackages = "com.atguigu.gulimail.product.feign")
@EnableDiscoveryClient
@MapperScan("com.atguigu.gulimail.product.dao")
@SpringBootApplication
public class GulimailProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimailProductApplication.class, args);
    }

}

SpringCache 缓存注解


(1)@CacheConfig: 主要用于配置该类中会用到的一些共用的缓存配置

(2)@Cacheable: 主要方法返回值加入缓存。同时在查询时,会先从缓存中取,若不存在才再发起对数据库的访问。,需要指定要放到那个名字的缓存(缓存的分区)

@Cacheable(value = “category”,key = “#root.methodName”)value 指定缓存的分区名字,,key = “#root.methodName” 指定key的名称为当前方法名

  @Cacheable(value = "category",key = "#root.methodName")
    @Override
    public List<CategoryEntity> getLeve1Categorys() {

        List<CategoryEntity> entities = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));
        return entities;
    }


(3)@CachePut:配置于函数上,能够根据参数定义条件进行缓存,与@Cacheable不同的是,每次回真实调用函数,所以主要用于数据新增和修改操作上。

在这里插入图片描述

 
    /** * 添加tasklog * @param tasklog * @return */
    @CachePut(value = CACHE_KEY, key = "#tasklog.id")
    public Tasklog create(Tasklog tasklog){
        System.out.println("CREATE");
        System.err.println (tasklog);
        taskLogMapper.insert(tasklog);
        return tasklog;
    }

(4)@CacheEvict:配置于函数上,通常用在删除方法上,用来从缓存中移除对应数据

在这里插入图片描述

 @CacheEvict(value = "category",allEntries = true)
    @Transactional
    @Override
    public void updateCascade(CategoryEntity category) {
        this.updateById(category);
        categoryBrandRelationService.updateCategory(category.getCatId(),category.getName());
    }


(5)@Caching:配置于函数上,组合多个Cache注解使用。

   @Caching(evict = {
            //删除缓存注解
            @CacheEvict(value = "category",key = "'getLeve1Categorys'"),
            @CacheEvict(value = "category",key = "'getCatalogJson'")
    })
    @Transactional
    @Override
    public void updateCascade(CategoryEntity category) {
        this.updateById(category);
        categoryBrandRelationService.updateCategory(category.getCatId(),category.getName());
    }


SpringCache 读模式下缓存问题的解决

缓存穿透:

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求(查询到一个NULL数据)
解决:缓存空数据:spring.cache.redis.cache-null-values=true

缓存击穿:

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
解决:加锁 在@Cacheable()中设置@Cacheable(sync=true)本地锁解决击穿

缓存雪崩:

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。(大量Key同时过期),和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决:指定过期时间:spring.cache.redis.time-to-live=3600000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值