Skip to content

默认情况下通过注解方式进行缓存时,没有过期时间永久生效,容易造成内存泄漏。我们可以修改redis缓存序列化器和配置manager过期时间,加入此配置项如果不指定过期时间,通过@Primary注解找到默认的过期时间配置。

java
@Configuration
public class RedisConfig {


    /**
     * 一小时
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisCacheManager cacheManager1Hour(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration config = instanceConfig(3600L);
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(config)
                .transactionAware()
                .build();
    }

    /**
     * 一天
     * @Primary 代表默认的
     * @param connectionFactory
     * @return
     */
    @Bean
    @Primary
    public RedisCacheManager cacheManager1Day(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration config = instanceConfig(3600 * 24L);
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(config)
                .transactionAware()
                .build();
    }

    /**
     * 序列化
     * @param ttl
     * @return
     */
    private RedisCacheConfiguration instanceConfig(Long ttl) {

        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
        // 去掉各种@JsonSerialize注解的解析
        objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false);
        // 只针对非空的值进行序列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 将类型序列化到属性json字符串中
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(ttl))
                .disableCachingNullValues() // 禁止缓存null值
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));

    }
}

使用

java
@Override
@Cacheable(value = {"product"},key = "#root.args[0]",cacheManager = "cacheManager1Hour") // 一小时后过期
public ProductDO findById(int id) {
    return productMapper.selectById(id);
}

@Override
@Cacheable(value = {"product_page"},key = "#root.methodName+'_'+#page+'_'+#size") // 默认一天
public IPage<ProductDO> page(int page, int size) {
    Page<ProductDO> pageInfo = new Page<>(page, size);
    return productMapper.selectPage(pageInfo, null);
}

查询Redis发现,数据已经生效

image-20210522103019393