package me.zhengjie.redis; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; import lombok.extern.slf4j.Slf4j; import me.zhengjie.utils.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 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.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; 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.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializationContext; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import java.time.Duration; /** * @author jie * @date 2018-11-24 */ @Slf4j @Configuration @EnableCaching // 自动配置 @ConditionalOnClass(RedisOperations.class) @EnableConfigurationProperties(RedisProperties.class) public class RedisConfig extends CachingConfigurerSupport { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private int timeout; @Value("${spring.redis.jedis.pool.max-idle}") private int maxIdle; @Value("${spring.redis.jedis.pool.max-wait}") private long maxWaitMillis; @Value("${spring.redis.password}") private String password; @Value("${spring.redis.database}") private int database; /** * 配置 redis 连接池 * @return */ @Bean public JedisPool redisPoolFactory(){ JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxIdle(maxIdle); jedisPoolConfig.setMaxWaitMillis(maxWaitMillis); String pwd = StringUtils.isBlank(password) ? null : password; return new JedisPool(jedisPoolConfig, host, port, timeout, pwd, database); } /** * 设置 redis 数据默认过期时间,默认1天 * 设置@cacheable 序列化方式 * @return */ @Bean public RedisCacheConfiguration redisCacheConfiguration(){ FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig(); configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofDays(1)); return configuration; } @Bean(name = "redisTemplate") @ConditionalOnMissingBean(name = "redisTemplate") public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate template = new RedisTemplate<>(); //序列化 FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class); // value值的序列化采用fastJsonRedisSerializer template.setValueSerializer(fastJsonRedisSerializer); template.setHashValueSerializer(fastJsonRedisSerializer); // 全局开启AutoType,不建议使用 // ParserConfig.getGlobalInstance().setAutoTypeSupport(true); // 建议使用这种方式,小范围指定白名单 ParserConfig.getGlobalInstance().addAccept("me.zhengjie.domain"); ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.system.service.dto"); ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.system.domain"); ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.quartz.domain"); ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.monitor.domain"); ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.security.security"); // key的序列化采用StringRedisSerializer template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setConnectionFactory(redisConnectionFactory); return template; } /** * 自定义缓存key生成策略 * 使用方法 @Cacheable(keyGenerator="keyGenerator") * @return */ @Bean @Override public KeyGenerator keyGenerator() { return (target, method, params) -> { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { // 由于参数可能不同, hashCode肯定不一样, 缓存的key也需要不一样 sb.append(JSON.toJSONString(obj).hashCode()); } return sb.toString(); }; } }