springboot版本说明
所用版本为2.0.2.RELEASE
springboot默认缓存集成
配置基本环境
采用mybatis框架,对一个简单的javaBean对象进行相应的CRUD操作来测试缓存
application.yml的基本配置如下
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/test?useSSL=false
driver-class-name: com.mysql.jdbc.Driver
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*Mapper.xml
# 打印mapper的sql语句
logging:
level:
com:
nanc:
cache:
mapper: debug
# 控制台打印自动配置报告,方便的知道哪些自动配置类生效;
debug: true
开启基于注解的缓存
@EnableCaching
cache自动配置的原理
- 自动配置类:CacheAutoConfiguration
@Configuration
@ConditionalOnClass(CacheManager.class)
@ConditionalOnBean(CacheAspectSupport.class)
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
@EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
@AutoConfigureAfter({ CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class,
RedisAutoConfiguration.class })
@Import(CacheConfigurationImportSelector.class) //主要看此类
public class CacheAutoConfiguration {
//此方法引入相关的cacheConfig
static class CacheConfigurationImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
CacheType[] types = CacheType.values();
String[] imports = new String[types.length];
for (int i = 0; i < types.length; i++) {
imports[i] = CacheConfigurations.getConfigurationClass(types[i]);
}
return imports;
}
}
}
这里先看 @Import(CacheConfigurationImportSelector.class)
- 缓存的配置类有:
final class CacheConfigurations {
private static final Map<CacheType, Class<?>> MAPPINGS;
static {
Map<CacheType, Class<?>> mappings = new EnumMap<>(CacheType.class);
mappings.put(CacheType.GENERIC, GenericCacheConfiguration.class);
mappings.put(CacheType.EHCACHE, EhCacheCacheConfiguration.class);
mappings.put(CacheType.HAZELCAST, HazelcastCacheConfiguration.class);
mappings.put(CacheType.INFINISPAN, InfinispanCacheConfiguration.class);
mappings.put(CacheType.JCACHE, JCacheCacheConfiguration.class);
mappings.put(CacheType.COUCHBASE, CouchbaseCacheConfiguration.class);
mappings.put(CacheType.REDIS, RedisCacheConfiguration.class);
mappings.put(CacheType.CAFFEINE, CaffeineCacheConfiguration.class);
mappings.put(CacheType.SIMPLE, SimpleCacheConfiguration.class);
mappings.put(CacheType.NONE, NoOpCacheConfiguration.class);
MAPPINGS = Collections.unmodifiableMap(mappings);
}
-
生效的配置类:SimpleCacheConfiguration
举例:为什么RedisCacheConfiguration没有生效
因为在RedisCacheConfiguration这个类上面有此注解
@ConditionalOnBean(RedisConnectionFactory.class),但是在系统中无法找到RedisConnectionFactory这个类,所以RedisCacheConfiguration不会生效
@Configuration
@ConditionalOnMissingBean(CacheManager.class)
@Conditional(CacheCondition.class)
class SimpleCacheConfiguration {
private final CacheProperties cacheProperties;
private final CacheManagerCustomizers customizerInvoker;
SimpleCacheConfiguration(CacheProperties cacheProperties,
CacheManagerCustomizers customizerInvoker) {
this.cacheProperties = cacheProperties;
this.customizerInvoker = customizerInvoker;
}
@Bean
public ConcurrentMapCacheManager cacheManager() {
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
cacheManager.setCacheNames(cacheNames);
}
return this.customizerInvoker.customize(cacheManager);
}
}
ConcurrentMapCacheManager.png给容器中注册了一个ChcheManager:ConcurrentMapCacheManager
ConcurrentMapCacheManager作用:可以获取和创建ConcurrentMapCache类型的缓存组件
ConcurrentMapCache作用:是将数据保存在ConcurrentMap注意一下图的一些方法,在使用@Cacheable等注解时,会先用getCache(cacheName)去获取Cache,如果没有获取到就会依据该cacheName去创建一个Cache,然后再使用获取到的Cache进行相关的操作
缓存注解的介绍
几个重要概念&缓存注解
Cache | 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等 |
---|---|
CacheManager | 缓存管理器,管理各种缓存(Cache)组件 |
@Cacheable | 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,它不能用到#result的spel表达式,因为该注解会在方法被调用前执行 |
@CacheEvict | 清空缓存 |
@CachePut | 保证方法被调用,又希望结果被缓存。先调用目标方法,然后将目标方法的返回结果缓存起来 |
@EnableCaching | 开启基于注解的缓存 |
keyGenerator | 缓存数据时key生成策略 |
serialize | 缓存数据时value序列化策略 |
注解的主要参数
@Cacheable/@CachePut/@CacheEvict 主要的参数
名称 | 解释 | 示例 |
---|---|---|
value/cacheNames | 缓存的名称,在 spring 配置文件中定义,必须指定 至少一个 | 例如: @Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达 式编写,如果不指定,则缺省按照方法的所有参数 进行组合 | 例如: @Cacheable(key="#root.methodName+'['+#a0+']'"):类似于 :方法名[第一个参数的值];@Cacheable(value=”testcache”,key=”#userName”) |
keyGenerator | key的生成器,可以自己指定key的生成器组件id;key/keyGenerator: 二选一的组件,只用指定一个即可 | 需要先自定义一个KeyGenerator的实现类,并放入到容器中,然后直接使用即可@Cacheable(keyGenerator="KeyGenerator的实现类bean的名称") |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存/清除缓存,在 调用方法之前之后都能判断,所以不能使用方法的返回值#result | 例如: @Cacheable(value=”testcache”,condition=”#userNam e.length()>2”) |
allEntries (@CacheEvict ) | 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 | 例如: @CachEvict(value=”testcache”,allEntries=true) |
beforeInvocation (@CacheEvict) | 是否在方法执行前就清空,缺省为 false,如果指定 为 true,则在方法还没有执行的时候就清空缓存, 缺省情况下,如果方法执行抛出异常,则不会清空 缓存 | 例如: @CachEvict(value=”testcache”, beforeInvocation=true) |
unless (@CachePut) (@Cacheable) | 用于否决缓存的,不像condition,该表达式只在方 法执行之后判断,此时可以拿到返回值result进行判 断。条件为true不会缓存, fasle才缓存 | 例如: @Cacheable(value=”testcache”,unless=”#result == null”) |
SPEL表达式的元数据
Cache SpEL available metadata,其中key,condition,unless可以用到这些元数据
名字 | 位置 | 描述 | 示例 |
---|---|---|---|
methodName | root object | 当前被调用的方法名 | #root.methodName |
method | root object | 当前被调用的方法 | #root.method.name |
target | root object | 当前被调用的目标对象 | #root.target |
targetClass | root object | 当前被调用的目标对象类 | #root.targetClass |
args | root object | 当前被调用的方法的参数列表 | #root.args[0] |
caches | root object | 当前方法调用使用的缓存列表(如@Cacheable(value={"cache1", "cache2"})), 则有两个cache | #root.caches[0].name |
argument name | evaluation context | 方法参数的名字. 可以直接 #参数名 ,也可以使用 #p0或#a0 的 形式, 0代表参数的索引; | #iban 、 #a0 、 #p0 |
result | evaluation context | 方法执行后的返回值(仅当方法执行之后的判断有效,如 ‘unless’ , ’cache put’的表达式 ’cache evict’的表达式 beforeInvocation=false) | #result |
@Cacheable的运行流程
- 方法运行之前,先去CacheManager中查询相应名称的Cache(缓存组件);
// 默认是此CacheManager
org.springframework.cache.concurrent.ConcurrentMapCacheManager
public Cache getCache(String name) {
//获取cache
Cache cache = this.cacheMap.get(name);
if (cache == null && this.dynamic) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(name);
if (cache == null) {
//不存在就创建一个
cache = createConcurrentMapCache(name);
this.cacheMap.put(name, cache);
}
}
}
return cache;
}
//创建一个Cache
protected Cache createConcurrentMapCache(String name) {
SerializationDelegate actualSerialization = (isStoreByValue() ? this.serialization : null);
return new ConcurrentMapCache(name, new ConcurrentHashMap<>(256),
isAllowNullValues(), actualSerialization);
}
-
去Cache中查找缓存的内容,使用一个key,默认就是方法的参数值;
key是按照某种策略生成的:默认是使用keyGenerator(默认使用org.springframework.cache.interceptor.SimpleKeyGenerator)
SimpleKeyGenerator的默认侧策略:
如果没有参数: key=SimpleKey.EMPTY
如果一个参数:key=参数的值
如果多个参数:key=new SimpleKey(params)
public class SimpleKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
return generateKey(params);
}
/**
* Generate a key based on the specified parameters.
*/
public static Object generateKey(Object... params) {
//没有参数
if (params.length == 0) {
return SimpleKey.EMPTY;
}
//一个参数
if (params.length == 1) {
Object param = params[0];
if (param != null && !param.getClass().isArray()) {
return param;
}
}
//多个参数
return new SimpleKey(params);
}
}
-
没有查到缓存就调用目标方法
// 可以看此类的这个方法 org.springframework.cache.interceptor.CacheAspectSupport#execute(org.springframework.cache.interceptor.CacheOperationInvoker, java.lang.reflect.Method, org.springframework.cache.interceptor.CacheAspectSupport.CacheOperationContexts) //部分代码 if (cacheHit != null && cachePutRequests.isEmpty() && !hasCachePut(contexts)) { // If there are no put requests, just use the cache hit cacheValue = cacheHit.get(); returnValue = wrapCacheValue(method, cacheValue); } else { // Invoke the method if we don't have a cache hit returnValue = invokeOperation(invoker); cacheValue = unwrapReturnValue(returnValue); }
- 将目标方法返回的结果,放进缓存
@Cahceput的使用注意事项
@Cacheable(cacheNames = "emp",key="#id")
public Employee getById(Integer id){
System.out.println("查询 " + id + " 号员工");
return employeeMapper.getById(id);
}
// 注意:需要将key值指定为一样的,才能更新相应的缓存
@CachePut(value = "emp",key="#result.id")
public Integer updateEmp(Employee employee) {
return employeeMapper.updateById(employee);
}
@CacheEvict 缓存清除
key:指定要清除的缓存的缓存
allEntries=true:指定删除指定cache下的所有缓存,此时就不用指定key了
beforeInvocation:缓存的清除是否在方法之前执行
默认值:falst,在方法执行之后执行的
方法之前/之后执行的区别:
如果方法执行期间除了异常,在方法之后执行就不能成功的删除缓存了
//会清除名称为“emp”这个cache下所有缓存的数据
@CacheEvict(value = "emp",allEntries = true)
public Integer deleteById(Integer id){
return employeeMapper.deleteById(id);
}
@Caching注解
org.springframework.cache.annotation.Caching
这是一个组合注解
@Caching(
cacheable = {
@Cacheable(value = "emp", key="#lastName")//以lastName为key,放一份缓存
},
put = {
@CachePut(value = "emp",key = "#result.id"),//以id为key,放一份缓存
@CachePut(value = "emp", key="#result.email")//以email为key,放一份缓存
}
)
public Employee getByName(String lastName){
return employeeMapper.getByName(lastName);
}
调用一次方法,再调用一次用断点查看缓存的情况
QQ截图20180601135542.png@CacheConfig(cacheNames = "emp")
@Service
@CacheConfig(cacheNames = "emp") //放到类上,里面使用到的@Cacheable等注解,就不用再指定cacheNames
public class EmployeeService {
springboot集成redis缓存
- 导入相关依赖
<!-- 整合redis需要的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 在application.yml添加相关配置
spring:
# redis相关配置
redis:
host: localhost
port: 6379
database: 2
原理解释
引入redis的starter,容器中保存的是RedisCacheManager
@Configuration
@ConditionalOnClass(CacheManager.class)
@ConditionalOnBean(CacheAspectSupport.class)
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")//注意CacheManager
@EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
@AutoConfigureAfter({ CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class,
RedisAutoConfiguration.class })//优先导入RedisAutoConfiguration等
@Import(CacheConfigurationImportSelector.class) //首先看这个要引入的类
public class CacheAutoConfiguration {
CacheConfigurationImportSelector.class里面要导入的类,生效的是RedisCacheConfiguration,它向容器中注入了RedisCacheManager,其他的都配置了@ConditionalOnMissingBean(CacheManager.class),所以只有这个生效
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
@ConditionalOnBean(RedisConnectionFactory.class)
@ConditionalOnMissingBean(CacheManager.class)
@Conditional(CacheCondition.class)
class RedisCacheConfiguration {
//向容器中注入了RedisCacheManager
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,
ResourceLoader resourceLoader) {
RedisCacheManagerBuilder builder = RedisCacheManager
.builder(redisConnectionFactory)
.cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
}
return this.customizerInvoker.customize(builder.build());
}
修改默认的序列化器
- 修改RedisTemplate,StringRedisTemplate的默认序列化器
// 添加自己的配置类
@Configuration
public class MyRedisConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//fastjson的序列化器
//FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
//设置序列化器
template.setDefaultSerializer(serializer);
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
//fastjson的序列化器
FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
//Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
template.setValueSerializer(serializer);
//设置序列化器
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
- 修改使用@Cacheable等注解时,不同缓存名称下,缓存数据的时效问题以及相关的序列化器
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
.builder(redisConnectionFactory)
.cacheDefaults(redisCacheConfiguration(Duration.ofDays(30)));
//配置多个不同名称的缓存
Map<String, RedisCacheConfiguration> map = ImmutableMap.<String,RedisCacheConfiguration>builder()
.put("cache_1_minutes", redisCacheConfiguration(Duration.ofMinutes(1)))
.put("cache_10_minutes", redisCacheConfiguration(Duration.ofMinutes(10)))
.put("cache_1_hour", redisCacheConfiguration(Duration.ofHours(1)))
.put("cache_10_hour", redisCacheConfiguration(Duration.ofHours(10)))
.put("cache_1_day", redisCacheConfiguration(Duration.ofDays(1)))
.put("cache_7_days", redisCacheConfiguration(Duration.ofDays(7)))
.put("cache_30_days", redisCacheConfiguration(Duration.ofDays(30)))
.build();
builder.withInitialCacheConfigurations(map);
return builder.build();
}
/**
* 启用@Cacheable等注解时,redis里面用到的key--value的序列化
* key = new StringRedisSerializer()
* value = new JdkSerializationRedisSerializer()
* 以及缓存的时限
*
*
* @return
*/
public org.springframework.data.redis.cache.RedisCacheConfiguration redisCacheConfiguration(Duration duration){
// TODO: 2018/6/1 尚未解决 如何使用json形式的序列化器,因为里面的泛型如果指定为Object的话,就无法转换成正确的类型,如果指定成具体的Entity的话,使用范围太窄
FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
//configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer)).entryTtl(duration);
//key的前缀不添加 cacheNames
configuration = configuration.disableKeyPrefix();
//设置缓存的时限
configuration = configuration.entryTtl(duration);
//configuration.s
return configuration;
}
RedisCacheConfiguration的简单说明:
QQ截图20180602095813.png为什么可以配置多个不同名称的缓存
package org.springframework.data.redis.cache;
public class RedisCacheManager extends AbstractTransactionSupportingCacheManager {
// 缓存名称--对应的RedisCacheConfiguration配置
private final Map<String, RedisCacheConfiguration> initialCacheConfiguration;
//初始化的时候,会用initialCacheConfiguration里面的内容创建好相应的RedisCache
@Override
protected Collection<RedisCache> loadCaches() {
List<RedisCache> caches = new LinkedList<>();
for (Map.Entry<String, RedisCacheConfiguration> entry :initialCacheConfiguration.entrySet()) {
caches.add(createRedisCache(entry.getKey(), entry.getValue()));
}
return caches;
}
/*
创建缓存,如果没有配置,会查找默认的RedisCacheConfiguration,但是这个默认的RedisCacheConfiguration是从哪里来的?
是我们自定义RedisCacheManager的时候,自己传进来的
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
.builder(redisConnectionFactory)
.cacheDefaults(redisCacheConfiguration(Duration.ofDays(30)));
*/
protected RedisCache createRedisCache(String name, @Nullable RedisCacheConfiguration cacheConfig) {
return new RedisCache(name, cacheWriter, cacheConfig != null ? cacheConfig : defaultCacheConfig);
}
解决不同实体无法使用JSON格式的序列化器问题
配置多个CacheManger,在使用注解的时候,为其指定cacheManager属性即可
最终配置如下:
package com.nanc.cache.config;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.google.common.collect.ImmutableMap;
import com.nanc.cache.entity.Employee;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import java.net.UnknownHostException;
import java.time.Duration;
import java.util.Map;
@Configuration
public class MyRedisConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//fastjson的序列化器
//FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
//设置序列化器
template.setDefaultSerializer(serializer);
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
//fastjson的序列化器
FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
//Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
template.setValueSerializer(serializer);
//设置序列化器
template.setConnectionFactory(redisConnectionFactory);
return template;
}
/**
* @Primary 配置默认的缓存管理器
* valueSerializationPair:使用默认的JdkSerializationRedisSerializer()
* 使用方式:如果不指定cacheManagers属性,就会使用默认的CacheManager
* @Cacheable(value = "cache_1_minutes",keyGenerator = "myKeyGenerator")
* @param redisConnectionFactory
* @return
*/
@Primary
@Bean
public RedisCacheManager defaultCacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
.builder(redisConnectionFactory)
.cacheDefaults(redisCacheConfiguration(null, Duration.ofDays(30)));
//可以抽取的公共配置
Map<String, RedisCacheConfiguration> map = ImmutableMap.<String,RedisCacheConfiguration>builder()
.put("cache_1_minutes", redisCacheConfiguration(null, Duration.ofMinutes(1)))
.put("cache_10_minutes", redisCacheConfiguration(null, Duration.ofMinutes(10)))
.put("cache_1_hour", redisCacheConfiguration(null, Duration.ofHours(1)))
.put("cache_10_hour", redisCacheConfiguration(null,Duration.ofHours(10)))
.put("cache_1_day", redisCacheConfiguration(null,Duration.ofDays(1)))
.put("cache_7_days", redisCacheConfiguration(null,Duration.ofDays(7)))
.put("cache_30_days", redisCacheConfiguration(null,Duration.ofDays(30)))
.build();
builder.withInitialCacheConfigurations(map);
return builder.build();
}
/**
* 为employee配置一个单独的RedisCacheManager
* 同理,如果Department也想把数据以json的形式放入缓存,再添加一个RedisCacheManager即可
*
*
* 使用方式:@Cacheable(value = "cache_1_minutes",keyGenerator = "myKeyGenerator",cacheManager = "employeeCacheManager")
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisCacheManager employeeCacheManager(RedisConnectionFactory redisConnectionFactory) {
//employee的使用FastJSON的序列化器
FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Employee.class);
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
.builder(redisConnectionFactory)
.cacheDefaults(redisCacheConfiguration(serializer, Duration.ofDays(30)));
Map<String, RedisCacheConfiguration> map = ImmutableMap.<String,RedisCacheConfiguration>builder()
.put("cache_1_minutes", redisCacheConfiguration(serializer, Duration.ofMinutes(1)))
.put("cache_10_minutes", redisCacheConfiguration(serializer, Duration.ofMinutes(10)))
.put("cache_1_hour", redisCacheConfiguration(serializer, Duration.ofHours(1)))
.put("cache_10_hour", redisCacheConfiguration(serializer,Duration.ofHours(10)))
.put("cache_1_day", redisCacheConfiguration(serializer,Duration.ofDays(1)))
.put("cache_7_days", redisCacheConfiguration(serializer,Duration.ofDays(7)))
.put("cache_30_days", redisCacheConfiguration(serializer,Duration.ofDays(30)))
.build();
builder.withInitialCacheConfigurations(map);
return builder.build();
}
/**
* 启用@Cacheable等注解时,redis里面用到的key--value的序列化
* key = new StringRedisSerializer()
* value = new JdkSerializationRedisSerializer()
* 以及缓存的时效
*
*
* @return
*/
public org.springframework.data.redis.cache.RedisCacheConfiguration redisCacheConfiguration(RedisSerializer serializer, Duration duration){
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
if (null != serializer) {
configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));
}
//key的前缀不添加 cacheNames
configuration = configuration.disableKeyPrefix();
//设置缓存的时效
configuration = configuration.entryTtl(duration);
//configuration.s
return configuration;
}
}
网友评论