①、什么是spring-cache:
Spring Cache 是Spring 提供的一整套的缓存解决方案,它不是具体的缓存实现,它只提供一整套的接口和代码规范、配置、注解等,用于整合各种缓存方案,比如Redis、Caffeine、Guava Cache、Ehcache。使用注解方式替代原有硬编码方式缓存,语法更加简单优雅!
**
org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'getAll' cannot be found on object of type 'org.springframework.cache.interceptor.CacheExpressionRootObject' - maybe not public
**
②、开整:
1)、将我们的spring-cache和Redis的依赖导入:
<!--spring-cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redis连接池-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
2)、spring-cache和Redis的配置:
spring:
cache:
type: redis # 缓存设置为Redis类型
redis: # 设置Redis连接信息
host: 124.221.70.206
port: 6379
jedis: # 设置Redis连接池
pool:
max-wait: 2000ms
min-idle: 2
max-idle: 8
max-active: 10
3)、声明缓存配置序列化方式【json】,配置缓存时间多样化配置
@Configuration
public class CacheConfiguration {
//配置缓存manager
@Bean
@Primary //同类型,多个bean,默认生效! 默认缓存时间1小时! 可以选择!
public RedisCacheManager cacheManagerHour(RedisConnectionFactory redisConnectionFactory){
RedisCacheConfiguration instanceConfig = instanceConfig(1 * 3600L);//缓存时间1小时
//构建缓存对象
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(instanceConfig)
.transactionAware()
.build();
}
//缓存一天配置
@Bean
public RedisCacheManager cacheManagerDay(RedisConnectionFactory redisConnectionFactory){
RedisCacheConfiguration instanceConfig = instanceConfig(24 * 3600L);//缓存时间1天
//构建缓存对象
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(instanceConfig)
.transactionAware()
.build();
}
/**
* 实例化具体的缓存配置!
* 设置缓存方式JSON
* 设置缓存时间 单位秒
* @param ttl
* @return
*/
private RedisCacheConfiguration instanceConfig(Long ttl){
//设置jackson序列化工具
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer
= new Jackson2JsonRedisSerializer<Object>(Object.class);
//常见jackson的对象映射器,并设置一些基本属性
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(MapperFeature.USE_ANNOTATIONS,false);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(ttl)) //设置缓存时间
.disableCachingNullValues()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
}
}
4)、我们在我们的springCache中主要通过以下注解整合我们Redis的硬编码:
- @EnableCaching
添加到启动类,开启缓存支持!
@SpringBootApplication
@EnableCaching //开启缓存支持
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class,args);
}
}
位置:添加到方法和类上
作用:调用方法,查询是否有缓存,有直接走缓存,没有走方法,将方法的返回值进行缓存!
参数:
value = String{} 配置缓存的 配置缓存‘分区’,相当于缓存的标示!
key = String 配置缓存的 ‘分区’下的具体表示,此处支持SpringEL表达式,动态命名
cacheManager = String 选择配置类中的缓存配置对象beanname,不选走默认!
condition = String 注解生效条件, 支持SpringEl表达式 例如: "#result != null"
结果不为null,进行缓存!
例如:
@Cacheable(value = "product",key = "#root.methodName+" +
"'-'+#productParamInteger.categoryID+" +
"'-'+#productParamInteger.currentPage+" +
"'-'+#productParamInteger.pageSize",cacheManager = "cacheManagerbean")
SpringEL表达式简单了解:
#开头
#root.method 被调用的方法
#root.methodName 被调用的方法名称
#root.target 调用方法的对象
#root.args 方法的参数对象数组 支持[index]获取具体参数
#result 方法执行后的结果
#形参名 直接获取行参数名称 支持ognl向下继续读取
注意:
缓存也分为curd
所以,设计缓存value和key的时候,多思考,后期还需要进行删除和替换动作!
位置:添加到方法和类上
作用:不影响方法使用,将方法的返回值,进行指定的key更新,通常添加到修改方法上!
参数:
value = String{} 配置缓存的 配置缓存‘分区’,相当于缓存的标示!
key = String 配置缓存的 ‘分区’下的具体表示,此处支持SpringEL表达式,动态命名
cacheManager = String 选择配置类中的缓存配置对象beanname,不选走默认!
condition = String 注解生效条件, 支持SpringEl表达式 例如: "#result != null"
结果不为null,进行更新!
例如:
@CachePut(key = "#id", condition = "#result != null"),
位置:添加到方法和类上
作用:不影响方法使用,将方法的返回值,进行指定的key失效,通常添加到删除方法上!
参数:
value = String{} 配置缓存的 配置缓存‘分区’,相当于缓存的标示!
key = String 配置缓存的 ‘分区’下的具体表示,此处支持SpringEL表达式,动态命名
cacheManager = String 选择配置类中的缓存配置对象beanname,不选走默认!
condition = String 注解生效条件, 支持SpringEl表达式 例如: "#result != null"
结果不为null,进行失效!
例如:
//单一失效
@CacheEvict(value = "student", key = "'saveCache01'")
//allEntries = true 删除分区所有的数据
@CacheEvict(value = "list.product",allEntries = true)
//多点失效
@Caching(evict = {
@CacheEvict(value = "student", key = "'saveCache01'"),
@CacheEvict(value = "student", key = "'saveCache02'")
})
位置:添加方法和类上
作用:多包涵注解,可以包含上面三个注解,用于复杂的缓存策略!
参数:
Cacheable [] cacheable 配置多个缓存
CachePut [] put 配置多个更新
CacheEvict [] evict() 配置多个缓存
例如:
订单模块
订单支付,需要更新订单缓存,还要清空热门商品缓存!