package com.farriver.bwf.service.config.cache; import com.alibaba.fastjson2.JSON; import com.farriver.bwf.common.utilities.FastJson2JsonRedisSerializer; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheResolver; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; import java.util.ArrayList; import java.util.List; @Configuration public class CacheConfig extends CachingConfigurerSupport { private static final Logger logger = LoggerFactory.getLogger(CacheConfig.class); @Resource private RedisConnectionFactory factory; @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); var serializer = new FastJson2JsonRedisSerializer(Object.class); var mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); serializer.setObjectMapper(mapper); template.setValueSerializer(serializer); template.setKeySerializer(new StringRedisSerializer()); template.afterPropertiesSet(); return template; } @Override @Bean public KeyGenerator keyGenerator() { return (o, method, objects) -> { String key = JSON.toJSONString(objects) .replace("\"", "") .replace("{", "") .replace("}", "") .replace(",", "") .replace(":", ""); return key; }; } @Bean @Override public CacheResolver cacheResolver() { var redisCacheManager = cacheManager(); List list = new ArrayList<>(); list.add(redisCacheManager); return new CustomCacheResolver(list); } @Bean @Override public CacheErrorHandler errorHandler() { return new IgnoreExceptionCacheErrorHandler(); } @Bean @Override public CacheManager cacheManager() { var redisSerializer = getRedisSerializer(); var serializationPair = RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer); var cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(300)) .serializeValuesWith(serializationPair); return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build(); } private RedisSerializer getRedisSerializer() { return new GenericJackson2JsonRedisSerializer(); } }