77、缓存---SpringCache---整合&体验@Cacheable

1、导入依赖

<!--缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

由于我们使用redis作为缓存,所以导入redis的依赖

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

2、写配置
(1)自动配置了哪些
CacheAutoConfiguration会导入RedisCacheConfiguration
自动配置好了缓存管理器RedisCacheManager
(2)配置使用redis作为缓存

(3)测试使用缓存

@Caching:组合以上多个操作
@CacheConfig:在类级别共享缓存的相同配置
开启缓存功能:在Springboot的Application类上加上注解@EnableCaching
只需要注解就能完成缓存操作

* 1、每一个需要缓存的数据都需要我们指定放到那个名字的缓存【缓存的分区(按照业务类型分)】
* 2、@Cacheable({"catagory"})
* 代表当前方法的结果需要缓存,如果缓存中有,方法不调用
* 如果缓存中没有,会调用方法,最后将方法的结果放入缓存


我们第一次调用会打印,但是以后调用就不会打印,并且redis中存储了我们的catalog数据

@Cacheable的默认行为:
1)如果缓存中有数据,就不会调用方法
2)key自动生成,缓存的名字::simpleKey[]是默认生成的key值
3)缓存的value值,默认使用的jdk序列化机制,将序列化后的数据放到redis
4)默认ttl过期时间为-1,即永不过期

我们需要几个自定义行为:
1)指定生成的缓存使用key


2)指定缓存的ttl时间======》配置文件编写spring.cache.redis.time-to-live=3600000(毫秒为单位)
3)将数据保存为json格式,这样别的语言也可以获取到
=》编写rediscache的配置文件,如下

把开启缓存的注解写到配置类上就行,不用再写到Application类上了。
缓存效果如下:

但是我们注意到ttl时间为-1,也就是说我们再application.properties中的配置没有用了
原因:package org.springframework.boot.autoconfigure.cache包下的RedisCacheConfiguration类中的默认方法determineConfiguration

下面的if都没有执行,因为我们的redisCacheConfiguration对象已经创建(不为空),解决办法如下:直接把所有的默认配置(if条件语句)都复制到我们的配置文件中

但是从源码中我们看到Redis redisProperties = this.cacheProperties.getRedis();
即redisProperties 是从CacheProperties类中获取的。我们查看CacheProperties源码

发现CacheProperties跟我们的配置文件中编写的cache的配置进行绑定了。因为CacheProperties指定了配置的前缀为spring.cache,并且我们配置文件中的有关cache的前缀也是spring.cache
发现没有将CacheProperties放到容器中(没有@Bean注解),所以我们无法在自己的配置类中注入这个类
解决办法:
@EnableConfigurationProperties(CacheProperties.class) //配置绑定功能
然后在我们的配置类就能注入CacheProperties类了
完整代码如下:

package com.gulimall.product.config;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@EnableConfigurationProperties(CacheProperties.class) //配置绑定功能
@EnableCaching //开启缓存
@Configuration
public class MyRedisConfig {
@Autowired
CacheProperties cacheProperties;
@Bean
public RedisCacheConfiguration redisCacheConfiguration(){
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();//使用它的默认配置,然后在它的基础上修改
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));//指定key的序列化
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));//指定value的序列化
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;
}
}

posted @   不是孩子了  阅读(123)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示