美文网首页spring全家桶
springbootCache整合redisTemplate/r

springbootCache整合redisTemplate/r

作者: codingKeeper | 来源:发表于2019-01-21 16:49 被阅读128次

    记录下整合的过程

    step1

    pom引用

     <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-data-redis</artifactId>
    </dependency>
    
    <!--如果需要redisson则需要引入-->
     <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson</artifactId>
                <version>3.8.0</version>
    </dependency>
    

    step2

    写配置类(名字任意)
    CacheConfiguration

    package com.jike.goldenpig.configration;
    
    import org.redisson.api.RedissonClient;
    import org.redisson.spring.cache.CacheConfig;
    import org.redisson.spring.cache.RedissonSpringCacheManager;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.interceptor.KeyGenerator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    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.serializer.GenericJackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    import java.lang.reflect.Method;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     *
     *
     * @author azhang.wang wangzhang367@163.com
     * @version CacheConfiguration.java, v 0.1 2017-02-21 10:38 AM Exp $
     */
    @Configuration
    public class CacheConfiguration extends CachingConfigurerSupport {
    
        public static final String DEFALUT_KEY="DEFALUT_KEY";
    
        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate template = new RedisTemplate();
    
            template.setConnectionFactory(factory);
    
            RedisSerializer keySerializer = new StringRedisSerializer();
    
            template.setKeySerializer(keySerializer);
            template.setHashKeySerializer(keySerializer);
    
            GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
    
            // 设置内容序列化类
            template.setValueSerializer(jsonSerializer);
    
            template.afterPropertiesSet();
    
            return template;
        }
        @Bean
        public CacheManager cacheManager(RedisTemplate redisTemplate) {
            RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
            //想要的一个过期时间集合,如果在集合内则会使用集合设定的过期时间过期
            Map<String, Long> expires = new HashMap<>();
            //设置特定namespace的过期时间,优雅点可以抽出公共的constants,这里为了演示直接写名称
            expires.put("people", 20L);
           //自定义一个默认的key,默认时间为60*60秒
            expires.put(DEFALUT_KEY, 60*60L);
    
            // 设置超时
            cacheManager.setExpires(expires);
    
            // 其他没有在expires中的namespace,设置的默认过期时间
            cacheManager.setDefaultExpiration(60 * 60);
    
            return cacheManager;
        }
    
        @Bean
        CacheManager cacheManager(RedissonClient redissonClient) {
            Map<String, CacheConfig> config = new HashMap<>(16);
            // create "testMap" cache with ttl = 24 minutes and maxIdleTime = 12 minutes
            config.put("user", new CacheConfig(20*1000, 12 * 60 * 1000));
            config.put("people", new CacheConfig(30*1000, 12 * 60 * 1000));
            return new RedissonSpringCacheManager(redissonClient, config);
    
        }
        @Override
        public KeyGenerator keyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object target, Method method, Object... params) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("CacheKey:");
                    sb.append(target.getClass().getSimpleName());
                    sb.append('.').append(method.getName()).append(":");
    
                    // 这里需要注意,参数太多的话考虑使用其他拼接方式
                    for (Object obj : params) {
                        if (obj != null) {
                            sb.append(obj.toString());
                            sb.append(".");
                        }
                    }
                    return sb.toString();
                }
            };
        }
    }
    
    

    以上 cacheManager 任意选择一个开启就好了。
    可以看到,不管哪种方式,给容器一个CacheManager即可

    step3

    使用方式

       int i = 0;
        @RequestMapping(value = "cache")
        @ResponseBody
        @Cacheable("people")
        public int cache(String a,String b) {
            i++;
            return i;
        }
        @RequestMapping(value = "cache2")
        @ResponseBody
        @Cacheable("user")
        public int cache2(String a,String b) {
            i++;
            return i;
        }
        @RequestMapping(value = "index")
        @Cacheable(CacheConfiguration.DEFALUT_KEY)
        public String index(ModelAndView mv) {
            mv.addObject("name", "rose");
            mv.setViewName("index");
            return "index";
        }
    

    这里直接在控制层添加了,大家自己玩吧。

    这里说下,使用redission和RedisTemplate的差别很小,但是他们保存在redis中的key是不一样的,原因是他们的失效机制不一样
    redission的会生成以下几个key


    redisson

    redisson使用的是持久化的key,同时绑定在自身的定时任务中,时间到了就会触发剔除动作,从而达到过期的效果
    RedisTemplate则是直接生成key,


    image.png
    这是跟redisson不同的地方,同时给他设定失效时间,但是会生成一个命名空间对应的key,来记录所有生成的记录,这个key也会失效,但是失效时间是循环的,目前还不知道为什么这样做,只能看到便于统计

    对比两者的结构,redisson使用的方式占用的redis中key的数量会少很多,由此带来一些便利,比如删除

    扩展可以参考这篇文章
    Spring Boot缓存实战 Redis 设置有效时间和自动刷新缓存,时间支持在配置文件中配置

    相关文章

      网友评论

        本文标题:springbootCache整合redisTemplate/r

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