demo
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.interceptor.KeyGenerator;
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.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Configuration
@EnableCaching
public class SpringCacheAutoConfiguration extends CachingConfigurerSupport {
@Override
@Bean
@Primary
public KeyGenerator keyGenerator() {
return (target, method, params) -> {
StringBuilder builder = new StringBuilder();
builder.append(target.getClass().getName());
builder.append("#").append(method.getName());
if (params.length == 0) {
builder.append("()");
} else {
builder.append("(");
for (Object obj : params) {
builder.append(obj).append(",");
}
builder.deleteCharAt(builder.length() - 1).append(")");
}
return builder.toString();
};
}
@Bean
@Primary
public CacheManager redisCacheManager(RedisTemplate<Object, Object> redisTemplate) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer((RedisSerializer<String>) redisTemplate.getKeySerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()))
.disableCachingNullValues()
.entryTtl(Duration.ofHours(3L));
return RedisCacheManager.builder(Objects.requireNonNull(redisTemplate.getConnectionFactory()))
.cacheDefaults(redisCacheConfiguration)
.transactionAware()
.withInitialCacheConfigurations(this.getRedisCacheConfigurationMap())
.build();
}
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
redisCacheConfigurationMap.put("test-key", this.getRedisCacheConfigurationWithTtl(6));
return redisCacheConfigurationMap;
}
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer hours) {
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.ofHours(hours));
return redisCacheConfiguration;
}
@Bean
public CacheManager caffeineCacheManager() {
Caffeine<Object, Object> caffeine = Caffeine.newBuilder()
.initialCapacity(50)
.maximumSize(1000)
.expireAfterWrite(Duration.ofHours(3L));
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCaffeine(caffeine);
caffeineCacheManager.setAllowNullValues(false);
return caffeineCacheManager;
}
}