集成结构
- 将各类厂商Oss配置存入数据库
- 项目启动初始化,读取配置存入缓存
- 定义一个Oss的Factory的工厂类
- 在第一次调用时,创建Client并根据厂商类型存入工厂类的Map中进行缓存
- 后续每次获取时判断是否为空或者配置不同如果没变就直接返回Client实例
初始化
-
定义类实现ApplicationRunner接口并重写方法run(),可以在Spring容器加载后执行,适用于初始化,读取缓存的操作
@Slf4j @RequiredArgsConstructor @Component public class SystemApplicationRunner implements ApplicationRunner { private final ISysOssConfigService ossConfigService; @Override public void run(ApplicationArguments args) throws Exception { ossConfigService.init(); log.info("初始化OSS配置成功"); } }
-
获取存在数据库的各类Oss配置,把当前 ( 状态为0 ) 的配置存在Redis中,如果获取图片时没有厂商就直接使用Redis中存储的厂商
public void init() { List<SysOssConfig> list = baseMapper.selectList(); // 加载OSS初始化配置 for (SysOssConfig config : list) { String configKey = config.getConfigKey(); if ("0".equals(config.getStatus())) { RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey); } CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config)); } }
Factory工厂实现Client的创建和获取
-
定义缓存用于存储不同厂商的Client
private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>();
-
通过厂商获取Client实例
@Slf4j public class OssFactory { private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>(); private static final ReentrantLock LOCK = new ReentrantLock(); /** * 获取默认实例 */ public static OssClient instance() { // 获取redis 默认类型 String configKey = RedisUtils.getCacheObject(OssConstant.DEFAULT_CONFIG_KEY); if (StringUtils.isEmpty(configKey)) { throw new OssException("文件存储服务类型无法找到!"); } return instance(configKey); } /** * 根据类型获取实例 */ public static OssClient instance(String configKey) { String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey); if (json == null) { throw new OssException("系统异常, '" + configKey + "'配置信息不存在!"); } OssProperties properties = JsonUtils.parseObject(json, OssProperties.class); // 使用租户标识避免多个租户相同key实例覆盖 String key = configKey; if (StringUtils.isNotBlank(properties.getTenantId())) { key = properties.getTenantId() + ":" + configKey; } OssClient client = CLIENT_CACHE.get(key); // 客户端不存在或配置不相同则重新构建 if (client == null || !client.checkPropertiesSame(properties)) { LOCK.lock(); try { client = CLIENT_CACHE.get(key); if (client == null || !client.checkPropertiesSame(properties)) { CLIENT_CACHE.put(key, new OssClient(configKey, properties)); log.info("创建OSS实例 key => {}", configKey); return CLIENT_CACHE.get(key); } } finally { LOCK.unlock(); } } return client; } }