package com.imyeyu.spring.config; import com.imyeyu.spring.bean.RedisConfigParams; import com.imyeyu.spring.util.Redis; import io.lettuce.core.api.StatefulConnection; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.cache.annotation.CachingConfigurer; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import java.time.Duration; /** * 抽象 RedisConfig * * @author 夜雨 * @version 2021-11-21 10:00 */ public abstract class AbstractRedisConfig implements CachingConfigurer { /** * 创建 Redis 配置 */ protected AbstractRedisConfig() { } /** * 构建 Redis 基本配置 * * @return Redis 基本配置 */ protected abstract RedisConfigParams configParams(); /** * 连接池配置 *

参考: *

	 *     GenericObjectPoolConfig<StatefulConnection<?, ?>> config = new GenericObjectPoolConfig<>();
	 *     config.setMaxTotal(config.getMaxActive());
	 *     config.setMinIdle(config.getMinIdle());
	 *     config.setMaxIdle(config.getMaxIdle());
	 *     config.setMaxWait(Duration.ofMillis(config.getMaxWait()));
	 * 
* * @return GenericObjectPoolConfig */ public abstract GenericObjectPoolConfig> getPoolConfig(); /** * Redis key 生成策略 *

参考: *

	 *     return (target, method, params) -> {
	 *         StringBuilder sb = new StringBuilder();
	 *         sb.append(target.getClass().getName());
	 *         sb.append(method.getName());
	 *         for (Object obj : params) {
	 *             sb.append(obj.toString());
	 *         }
	 *         return sb.toString();
	 *     };
	 * 
* * @return KeyGenerator */ public abstract KeyGenerator keyGenerator(); /** * 构造自定义 RedisTemplate * * @param database 数据库 * @param keySerializer 键序列化方式 * @param 键类型 * @param 值类型 * @return RedisTemplate */ public Redis getRedis(int database, RedisSerializer keySerializer) { return getRedis(database, keySerializer, null); } /** * 构造自定义 RedisTemplate *

针对同一服务器不同数据库 * * @param database 数据库 * @param keySerializer 键序列化方式 * @param valueSerializer 值序列化方式 * @param 键类型 * @param 值类型 * @return RedisTemplate */ public Redis getRedis(int database, RedisSerializer keySerializer, RedisSerializer valueSerializer) { RedisConfigParams configParams = configParams(); // 构建 Redis 配置 RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(); // 连接参数 config.setHostName(configParams.getHost()); config.setPort(configParams.getPort()); config.setPassword(RedisPassword.of(configParams.getPassword())); config.setDatabase(database); // 构造连接池 LettucePoolingClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder().commandTimeout(Duration.ofMillis(configParams.getTimeout())).poolConfig(getPoolConfig()).build(); // 重构连接工厂 LettuceConnectionFactory factory = new LettuceConnectionFactory(config, clientConfig); // 设置数据库 factory.afterPropertiesSet(); RedisTemplate rt = new RedisTemplate<>(); rt.setConnectionFactory(factory); rt.setKeySerializer(keySerializer); rt.setHashKeySerializer(keySerializer); if (valueSerializer != null) { rt.setValueSerializer(valueSerializer); rt.setHashValueSerializer(valueSerializer); } rt.setConnectionFactory(factory); rt.afterPropertiesSet(); return new Redis<>(rt, keySerializer); } }