鍍金池/ 問答/人工智能  Java/ SpringBoot 2.X @Cacheable,redis-cache 如何

SpringBoot 2.X @Cacheable,redis-cache 如何根據(jù)key設(shè)置緩存時間?

SpringBoot 2.x 以后,@Cacheable, Redis-cahce 的配置變動比較大

網(wǎng)上找了點資料,目前我的配置是

@Bean
    public RedisCacheConfiguration redisCacheConfiguration() {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
            RedisSerializationContext
                .SerializationPair
                .fromSerializer(jackson2JsonRedisSerializer)
        ).entryTtl(Duration.ofMinutes(30));

        return redisCacheConfiguration;
    }

使用上述代碼后,可以成功緩存,但不能對key指定緩存時間,

clipboard.png

如圖,兩個 key UserInfoList 和 key UserInfoListAnother 都是默認的30分鐘

2.X以后無法再使用 RedisCacheManager rcm = new RedisCacheManager(redisTemplate) 構(gòu)造方法來設(shè)置緩存時間,請問該如何配置?

回答
編輯回答
胭脂淚

google 了一晚上,終于找到了比較滿意的方法,下面是整個的 RedisCacheConfig 文件

@Configuration
public class RedisCacheConfig {

    @Bean
    public KeyGenerator simpleKeyGenerator() {
        return (o, method, objects) -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(o.getClass().getSimpleName());
            stringBuilder.append(".");
            stringBuilder.append(method.getName());
            stringBuilder.append("[");
            for (Object obj : objects) {
                stringBuilder.append(obj.toString());
            }
            stringBuilder.append("]");

            return stringBuilder.toString();
        };
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        return new RedisCacheManager(
            RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
            this.getRedisCacheConfigurationWithTtl(600), // 默認策略,未配置的 key 會使用這個
            this.getRedisCacheConfigurationMap() // 指定 key 策略
        );
    }

    private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
        Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
        redisCacheConfigurationMap.put("UserInfoList", this.getRedisCacheConfigurationWithTtl(3000));
        redisCacheConfigurationMap.put("UserInfoListAnother", this.getRedisCacheConfigurationWithTtl(18000));

        return redisCacheConfigurationMap;
    }

    private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
            RedisSerializationContext
                .SerializationPair
                .fromSerializer(jackson2JsonRedisSerializer)
        ).entryTtl(Duration.ofSeconds(seconds));

        return redisCacheConfiguration;
    }
}

要指定 key 的過期時間,只要在getRedisCacheConfigurationMap方法中添加就可以。
然后只需要 @Cacheable 就可以把數(shù)據(jù)存入 redis

    @Cacheable(value = "UserInfoList", keyGenerator = "simpleKeyGenerator") // 3000秒
    @Cacheable(value = "UserInfoListAnother", keyGenerator = "simpleKeyGenerator") // 18000秒
    @Cacheable(value = "DefaultKeyTest", keyGenerator = "simpleKeyGenerator") // 600秒,未指定的key,使用默認策略
    
2018年2月1日 12:37
編輯回答
莓森

使用Spring Boot了當(dāng)然是使用Redis的自動裝配了,只需要引入redis-starter即可開箱用
`

redisTemplate.opsForValue().set(key, value, expires, timeUnit)
   

`

補充一下你的Bean

@Bean
public RedisCacheConfiguration redisCacheConfiguration(RedisTemplate<String, Object> template, CacheStrategy stategy) {

    redisCacheManager.setExpires(strategy.getExpiresMap);
    return redisCacheConfiguration;
}

然后配置CacheStrategy類

public static final String KEY = "_TEST";

public static Long CACHE_TIME = 10000L;
private Map<String, Long> expiresMap = null;

@PostConstruct
public void init(){
    expiresMap = Maps.newHashMap();
    expiresMap.put(KEY, CACHE_TIME);
}

public Map<String, Long> getExpiresMap(){
    return this.expiresMap;
}

然后使用Cacheable注解的時候可以使用指定key,也可以使用Spring的自動生成策略key具體方法

@Cacheable(value = "", key =)// 自定義key策略
@Cacheable(value = "")//自動生成key策略


還有一種方式是使用SpEL表達式方式

@Cacheable(value = "example#${select.cache.timeout:1000}", key = "")//example 是cache容器名字 #后邊的是SpEL表達式


不知道是否可以直接解決你的問題,如果愿意你可以作一個參考

2018年4月10日 21:30