package com.imyeyu.api.config; import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.api.modules.common.entity.Multilingual; import com.imyeyu.spring.bean.RedisConfigParams; import com.imyeyu.spring.config.AbstractRedisConfig; import com.imyeyu.spring.util.Redis; import com.imyeyu.spring.util.RedisSerializers; import com.imyeyu.utils.Time; import io.lettuce.core.api.StatefulConnection; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.serializer.support.DeserializingConverter; import org.springframework.core.serializer.support.SerializingConverter; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationException; import org.springframework.lang.Nullable; import java.time.Duration; /** * Redis 配置 * * @author 夜雨 * @since 2021-02-23 21:36 */ @Data @Configuration @EqualsAndHashCode(callSuper = true) @EnableAutoConfiguration @ConfigurationProperties(prefix = "spring.redis") public class RedisConfig extends AbstractRedisConfig { @Autowired private ObjectMapper jackson; // ---------- 连接配置 ---------- /** 地址 */ private String host; /** 端口 */ private int port; /** 密码 */ private String password; /** Redis 逻辑库 */ private int database; @Override protected RedisConfigParams configParams() { return new RedisConfigParams() {{ setHost(host); setPort(port); setPassword(password); setTimeout(Time.SI * 8); setMaxActive(8); setMinIdle(1); setMaxIdle(8); }}; } /** @return 连接池配置 */ @Bean @Override public GenericObjectPoolConfig> getPoolConfig() { RedisConfigParams configArgs = configParams(); GenericObjectPoolConfig> config = new GenericObjectPoolConfig<>(); config.setMaxTotal(8); config.setMinIdle(configArgs.getMinIdle()); config.setMaxIdle(configArgs.getMaxIdle()); config.setMaxWait(Duration.ofMillis(-1)); return config; } /** @return key 生成策略 */ @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) { sb.append(obj.toString()); } return sb.toString(); }; } /** @return 分布式锁, ID: 尝试加锁次数 */ @Bean("redisLocker") public Redis getLockerRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.INTEGER); } /** @return 多语言环境,ID: {@link Multilingual} */ @Bean("redisLanguage") public Redis getLanguageRedisTemplate() { return getRedis(database, RedisSerializers.STRING, new RedisSerializer<>() { public Multilingual deserialize(@Nullable byte[] bytes) { if (bytes == null || bytes.length == 0) { return null; } try { return (Multilingual) new DeserializingConverter().convert(bytes); } catch (Exception var3) { throw new SerializationException("Cannot deserialize", var3); } } public byte[] serialize(@Nullable Multilingual multilingual) { if (multilingual == null) { return new byte[0]; } else { try { return new SerializingConverter().convert(multilingual); } catch (Exception var3) { throw new SerializationException("Cannot serialize", var3); } } } }); } @Bean("redisCaptcha") public Redis getCaptchaRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.STRING); } /** @return 文章访问记录,IP: [文章 ID] */ @Bean("redisLanguageMap") public Redis getLanguageMapRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.LONG); } /** @return 文章访问记录,IP: [文章 ID] */ @Bean("redisArticleRead") public Redis getArticleReadRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.LONG); } /** @return 用户登录经验标记,UID: NULL,暂时没有值,数据死亡时间为次日零时 */ @Bean("redisUserExpFlag") public Redis getUserExpFlagRedisTemplate() { return getRedis(database, RedisSerializers.LONG, RedisSerializers.STRING); } /** @return 用户登录令牌,令牌: 用户 ID */ @Bean("redisUserToken") public Redis getUserTokenRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.STRING); } /** @return 用户邮箱验证密钥,密钥: UID */ @Bean("redisUserEmailVerify") public Redis getUserEmailVerifyRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.LONG); } /** @return 用户重置密码密钥,密钥: UID */ @Bean("redisUserResetPWVerify") public Redis getUserResetPWVerifyRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.LONG); } /** @return 用户手机号验证码,手机号: 验证码 */ @Bean("redisUserPhoneVerify") public Redis getUserPhoneVerifyRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.STRING); } /** @return 接口访问控制,IP#方法: 生命周期内访问次数 */ @Bean("redisRateLimit") public Redis getRateLimitRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.INTEGER); } /** @return 系统配置,Key 枚举: String 配置值 */ @Bean("redisSetting") public Redis getSettingRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.STRING); } /** @return Minecraft 登录,令牌: 玩家 ID */ @Bean("redisMCPlayerToken") public Redis getMCPlayerLoginRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.LONG); } /** @return 共享剪切板,会话 ID: 内容 */ @Bean("redisClipboard") public Redis getClipboardRedisTemplate() { return getRedis(database, RedisSerializers.STRING, RedisSerializers.STRING); } }