一、Springboot整合SpringCache
1.导包
导入SpringCache
<!-- 引入springCache简化缓存开发-->
<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>
<!--排除lettuce,使用jedis 避免堆外内存溢出异常-->
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--引入jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
2.开启SpringCache功能
@EnableCaching
@EnableCaching
@SpringBootApplication
@EnableTransactionManagement
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.watching.gulimall.product.feign")
public class GulimallProductAppliication {
public static void main(String[] args) {
SpringApplication.run(GulimallProductAppliication.class,args);
}
}
3.编写SpringCache配置类
如果不配置SpringCache的缓存服务,SpringCache默认使用JAVA集合ConcurrentMap接口作为缓存服务。
如果导入了redis依赖,SpringCache的CacheAutoConfiguration会导入 RedisCacheConfiguration,自动配置好了缓存管理器,RedisCacheManager
package com.watching.gulimall.product.config;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author Watching
* * @date 2022/11/20
* * Describe:
*/
@EnableConfigurationProperties(CacheProperties.class)//该注解可以将CacheProperties加入ioc容器,便于我们自动注入使用
@Configuration
public class MyCacheConfig {
// @Autowired
// public CacheProperties cacheProperties;
/**
* 配置文件中的东西没有用上;
* 1、原来和配置文件绑定的配置类是这样子的
* @ConfigurationProperties(prefix = "spring.cache")
* public class CacheProperties
* 2、要让他生效
* @EnableConfigurationProperties (CacheProperties.class)
*
*/
@Bean
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
// config = config.entryTtl();
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
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;
}
}
4.编写SpringCache配置文件
spring.cache.type=redis
spring.cache.redis.time-to-live=3600000
#为键添加前缀,如果没有设置前缀,则以缓存的名字作为前缀
spring.cache.redis.key-prefix=CACHE_
#是否开启添加前缀
spring.cache.redis.use-key-prefix=true
#是否缓存空值,开启后防止缓存穿透,默认开启
spring.cache.redis.cache-null-values=true
二、SpringCache的基本操作
1.@Cacheable
注解在方法上,将方法的返回值存储在缓存中
eg:
@Cacheable(value="watching",key = "#root.methodName")
public String testCacheable(){
return "hello world";
}
@Cacheable
value的值为分区名。
key为缓存的‘键’,key支持SpEL表达式,具体语法可以查看@Cacheable源码。此外,如果不使用SpEL表达式,自己指定字符串作为‘键’,需要使用单引号,否则会被解析外SpEL表达式,如:@Cacheable(value="watching",key = "'mykey'")
2.@CacheEvict
注解在方法上,在方法结束后触发删除指定分区缓存
eg:
@CacheEvict(value="watching",key="'testCacheable'")
public void update(Person person){
personDao.update(person);
}
value的值为分区名。
key为缓存的‘键’,key支持SpEL表达式,具体语法可以查看@CacheEvict源码。此外,如果不使用SpEL表达式,自己指定字符串作为‘键’,需要使用单引号,否则会被解析外SpEL表达式,如:@CacheEvict(value="watching",key="'testCacheable'")
此外,@CacheEvict中还有一个属性allEntries
@CacheEvict(value = "watching",allEntries = true)
该代码意为,删除watching分区下的所有缓存
3.@Caching
注解在方法上,方法结束后,执行组合缓存操作,
@Caching(evict = {
@CacheEvict(value="watching",key="'testCacheable1'")
@CacheEvict(value="watching",key="'testCacheable2'")
})
public void update(Person person){
personDao.update(person);
}
@Caching的源码如下
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}
修改数据库保证缓存一致性的两种模式
失效模式,失效模式可以使用@CacheEvict
双写模式,双写模式可以使用@CachePut
未完待续…