美文网首页
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地址

    相关文章

      网友评论

          本文标题:springboot集成redis缓存

          本文链接:https://www.haomeiwen.com/subject/swfrsftx.html