美文网首页
springboot集成redis缓存

springboot集成redis缓存

作者: 缓慢移动的蜗牛 | 来源:发表于2018-06-02 11:33 被阅读0次

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);
   }
}

给容器中注册了一个ChcheManager:ConcurrentMapCacheManager
ConcurrentMapCacheManager作用:可以获取和创建ConcurrentMapCache类型的缓存组件
ConcurrentMapCache作用:是将数据保存在ConcurrentMap

注意一下图的一些方法,在使用@Cacheable等注解时,会先用getCache(cacheName)去获取Cache,如果没有获取到就会依据该cacheName去创建一个Cache,然后再使用获取到的Cache进行相关的操作

ConcurrentMapCacheManager.png

缓存注解的介绍

几个重要概念&缓存注解

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;
    }

}

demo地址

相关文章