package com.metalloop.common.redis; import com.metalloop.common.redis.properties.CacheManagerProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; 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.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.stereotype.Component; import java.time.Duration; import java.util.HashMap; import java.util.Map; /** * Redis 配置类,键强制为string序列化,值默认使用json序列化,同时支持java序列化、string序列化 * 根据需求自行选择 * 缓存默认启用 * * @author zhaowenhao */ @SuppressWarnings("DuplicatedCode") @EnableConfigurationProperties({RedisProperties.class, CacheManagerProperties.class}) @EnableCaching @Component public class RedisAutoConfigure { @Autowired private CacheManagerProperties cacheManagerProperties; @Bean public RedisSerializer redisKeyStringSerializer() { return RedisSerializer.string(); } @Bean public RedisSerializer redisValueJsonSerializer() { return RedisSerializer.json(); } @Bean public RedisSerializer redisValueJavaSerializer() { return RedisSerializer.java(); } /** * string-json RedisTemplate配置,默认使用 * * @param factory RedisConnectionFactory * @param redisKeyStringSerializer RedisSerializer */ @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory, RedisSerializer redisKeyStringSerializer, RedisSerializer redisValueJsonSerializer) { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); redisTemplate.setDefaultSerializer(redisValueJsonSerializer); redisTemplate.setKeySerializer(redisKeyStringSerializer); redisTemplate.setHashKeySerializer(redisKeyStringSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * string-string RedisTemplate配置 * * @param redisConnectionFactory RedisConnectionFactory */ @Bean @ConditionalOnMissingBean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } /** * string-java RedisTemplate配置 * * @param factory RedisConnectionFactory * @param redisKeyStringSerializer RedisSerializer */ @Bean @ConditionalOnMissingBean(name = "javaRedisTemplate") public RedisTemplate javaRedisTemplate(RedisConnectionFactory factory, RedisSerializer redisKeyStringSerializer, RedisSerializer redisValueJavaSerializer) { RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setDefaultSerializer(redisValueJavaSerializer); template.setKeySerializer(redisKeyStringSerializer); template.setHashKeySerializer(redisKeyStringSerializer); template.afterPropertiesSet(); return template; } @Bean(name = "cacheManager") @Primary public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, RedisSerializer redisKeyStringSerializer, RedisSerializer redisValueJsonSerializer) { RedisCacheConfiguration difConf = getDefConf(redisKeyStringSerializer, redisValueJsonSerializer).entryTtl(Duration.ofHours(1)); // 自定义的缓存过期时间配置 int configSize = cacheManagerProperties.getConfigs() == null ? 0 : cacheManagerProperties.getConfigs().size(); Map redisCacheConfigurationMap = new HashMap<>(configSize); if (configSize > 0) { cacheManagerProperties.getConfigs().forEach(e -> { RedisCacheConfiguration conf = getDefConf(redisKeyStringSerializer, redisValueJsonSerializer).entryTtl(Duration.ofSeconds(e.getSecond())); redisCacheConfigurationMap.put(e.getKey(), conf); }); } return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(difConf).withInitialCacheConfigurations(redisCacheConfigurationMap).build(); } @Bean public KeyGenerator keyGenerator() { return (target, method, objects) -> { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(":").append(method.getName()).append(":"); for (Object obj : objects) { sb.append(obj.toString()); } return sb.toString(); }; } private RedisCacheConfiguration getDefConf(RedisSerializer redisKeyStringSerializer, RedisSerializer redisValueJsonSerializer) { return RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues().computePrefixWith(cacheName -> "cache".concat(":").concat(cacheName).concat(":")).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisKeyStringSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisValueJsonSerializer)); } }