| | |
| | | import com.vincent.rsf.server.system.entity.Config; |
| | | import com.vincent.rsf.server.system.enums.ConfigType; |
| | | import com.vincent.rsf.server.system.enums.StatusType; |
| | | import com.vincent.rsf.server.common.service.RedisService; |
| | | import com.vincent.rsf.server.system.config.ConfigCacheProperties; |
| | | import com.vincent.rsf.server.system.mapper.ConfigMapper; |
| | | import com.vincent.rsf.server.system.service.ConfigService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.PostConstruct; |
| | |
| | | @Slf4j |
| | | public class ConfigServiceImpl extends ServiceImpl<ConfigMapper, Config> implements ConfigService { |
| | | |
| | | /** 与 {@link RedisService#set(String, String, Object, Integer)} 的 flag 段一致:sys_config 非永久 key,见 {@link ConfigCacheProperties} */ |
| | | private static final String REDIS_FLAG_SYS_CONFIG = "SYS_CONFIG"; |
| | | |
| | | public static final Map<String, Config> CONFIG_CACHE = new ConcurrentHashMap<>(); |
| | | |
| | | @Autowired(required = false) |
| | | private RedisService redisService; |
| | | @Autowired |
| | | private ConfigCacheProperties configCacheProperties; |
| | | |
| | | @PostConstruct |
| | | public void init() { |
| | |
| | | } catch (Exception e) { |
| | | log.warn("配置缓存初始化失败,跳过配置表加载,后续按默认流程处理", e); |
| | | } |
| | | } |
| | | |
| | | private boolean redisReady() { |
| | | return redisService != null && Boolean.TRUE.equals(redisService.initialize); |
| | | } |
| | | |
| | | private static boolean isEffectiveConfig(Config c) { |
| | | return c != null && (c.getDeleted() == null || c.getDeleted() == 0); |
| | | } |
| | | |
| | | private Config loadConfigFromDb(String flag) { |
| | | return getOne(new LambdaQueryWrapper<Config>() |
| | | .eq(Config::getFlag, flag) |
| | | .eq(Config::getDeleted, 0), false); |
| | | } |
| | | |
| | | private Config tryRedisGetConfig(String flag) { |
| | | try { |
| | | return redisService.get(REDIS_FLAG_SYS_CONFIG, flag); |
| | | } catch (Exception e) { |
| | | log.debug("sys_config Redis get flag={}", flag, e); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | private void tryRedisSetexConfig(String flag, Config loaded) { |
| | | try { |
| | | int ttl = Math.max(1, configCacheProperties.getRedisTtlSeconds()); |
| | | redisService.set(REDIS_FLAG_SYS_CONFIG, flag, loaded, ttl); |
| | | } catch (Exception e) { |
| | | log.warn("sys_config Redis setex flag={}", flag, e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void evictSysConfigRedis(String flag) { |
| | | if (!redisReady() || StringUtils.isBlank(flag)) { |
| | | return; |
| | | } |
| | | try { |
| | | redisService.delete(REDIS_FLAG_SYS_CONFIG, flag); |
| | | } catch (Exception e) { |
| | | log.warn("sys_config Redis evict flag={}", flag, e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public Config getCachedOrLoad(String flag) { |
| | | if (StringUtils.isBlank(flag)) { |
| | | return null; |
| | | } |
| | | if (redisReady()) { |
| | | Config fromRedis = tryRedisGetConfig(flag); |
| | | if (isEffectiveConfig(fromRedis)) { |
| | | CONFIG_CACHE.put(flag, fromRedis); |
| | | return fromRedis; |
| | | } |
| | | Config loaded = loadConfigFromDb(flag); |
| | | if (loaded != null) { |
| | | CONFIG_CACHE.put(flag, loaded); |
| | | tryRedisSetexConfig(flag, loaded); |
| | | } |
| | | return loaded; |
| | | } |
| | | Config cached = CONFIG_CACHE.get(flag); |
| | | if (isEffectiveConfig(cached)) { |
| | | return cached; |
| | | } |
| | | if (cached != null) { |
| | | CONFIG_CACHE.remove(flag); |
| | | } |
| | | Config loaded = loadConfigFromDb(flag); |
| | | if (loaded != null) { |
| | | CONFIG_CACHE.put(flag, loaded); |
| | | } |
| | | return loaded; |
| | | } |
| | | |
| | | @Override |
| | |
| | | throw new UnsupportedOperationException("Unsupported ConfigType: " + configType); |
| | | } |
| | | |
| | | return this.updateById(config); |
| | | boolean ok = this.updateById(config); |
| | | if (ok) { |
| | | evictSysConfigRedis(key); |
| | | } |
| | | return ok; |
| | | } |
| | | |
| | | private List<Config> safeList(LambdaQueryWrapper<Config> wrapper) { |
| | |
| | | if (!this.update(new LambdaUpdateWrapper<Config>().set(Config::getVal, config.getVal()).eq(Config::getFlag, config.getFlag()))) { |
| | | throw new CoolException("修改失败!!"); |
| | | } |
| | | Config fresh = getOne(new LambdaQueryWrapper<Config>() |
| | | .eq(Config::getFlag, config.getFlag()) |
| | | .eq(Config::getDeleted, 0), false); |
| | | if (fresh != null) { |
| | | CONFIG_CACHE.put(fresh.getFlag(), fresh); |
| | | } else { |
| | | CONFIG_CACHE.remove(config.getFlag()); |
| | | } |
| | | evictSysConfigRedis(config.getFlag()); |
| | | return R.ok(); |
| | | } |
| | | |