refactor: 优化本地存储库注册

This commit is contained in:
Charles7c 2024-01-05 21:29:24 +08:00
parent 635de6b321
commit 918e897838

View File

@ -18,11 +18,9 @@ package top.charles7c.continew.admin.system.service.impl;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletContext;
import lombok.RequiredArgsConstructor;
@ -30,17 +28,10 @@ import org.dromara.x.file.storage.core.FileStorageProperties;
import org.dromara.x.file.storage.core.FileStorageService;
import org.dromara.x.file.storage.core.FileStorageServiceBuilder;
import org.dromara.x.file.storage.core.platform.FileStorage;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.util.UrlPathHelper;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
@ -55,6 +46,7 @@ import top.charles7c.continew.admin.system.model.resp.StorageResp;
import top.charles7c.continew.admin.system.service.FileService;
import top.charles7c.continew.admin.system.service.StorageService;
import top.charles7c.continew.starter.core.constant.StringConstants;
import top.charles7c.continew.starter.core.util.SpringUtils;
import top.charles7c.continew.starter.core.util.URLUtils;
import top.charles7c.continew.starter.core.util.validate.CheckUtils;
import top.charles7c.continew.starter.core.util.validate.ValidationUtils;
@ -74,7 +66,6 @@ public class StorageServiceImpl
@Resource
private FileService fileService;
private final ApplicationContext applicationContext;
private final FileStorageService fileStorageService;
@Override
@ -89,20 +80,24 @@ public class StorageServiceImpl
@Override
public void update(StorageReq req, Long id) {
CheckUtils.throwIf(Boolean.TRUE.equals(req.getIsDefault()) && this.isDefaultExists(id), "请先取消原有默认存储库");
String code = req.getCode();
CheckUtils.throwIf(this.isCodeExists(code, id), "修改失败,[{}] 已存在", code);
DisEnableStatusEnum newStatus = req.getStatus();
StorageDO oldStorage = super.getById(id);
CheckUtils.throwIf(
Boolean.TRUE.equals(oldStorage.getIsDefault()) && DisEnableStatusEnum.DISABLE.equals(req.getStatus()),
Boolean.TRUE.equals(oldStorage.getIsDefault()) && DisEnableStatusEnum.DISABLE.equals(newStatus),
"[{}] 是默认存储库,不允许禁用", oldStorage.getName());
if (DisEnableStatusEnum.ENABLE.equals(oldStorage.getStatus())
|| DisEnableStatusEnum.DISABLE.equals(req.getStatus())) {
DisEnableStatusEnum oldStatus = oldStorage.getStatus();
if (DisEnableStatusEnum.ENABLE.equals(oldStatus) || DisEnableStatusEnum.DISABLE.equals(newStatus)) {
this.unload(BeanUtil.copyProperties(oldStorage, StorageReq.class));
}
if (DisEnableStatusEnum.ENABLE.equals(req.getStatus())) {
if (DisEnableStatusEnum.ENABLE.equals(newStatus)) {
this.load(req);
}
if (Boolean.TRUE.equals(req.getIsDefault())) {
CheckUtils.throwIf(!DisEnableStatusEnum.ENABLE.equals(oldStatus), "请先启用该存储库");
CheckUtils.throwIf(this.isDefaultExists(id), "请先取消原有默认存储库");
}
super.update(req, id);
}
@ -145,7 +140,7 @@ public class StorageServiceImpl
config.setStoragePath(bucketName);
fileStorageList
.addAll(FileStorageServiceBuilder.buildLocalPlusFileStorage(Collections.singletonList(config)));
this.registerResource(MapUtil.of(URLUtil.url(req.getDomain()).getPath(), bucketName), false);
SpringUtils.registerResourceHandler(MapUtil.of(URLUtil.url(req.getDomain()).getPath(), bucketName));
}
case S3 -> {
String accessKey = req.getAccessKey();
@ -174,7 +169,7 @@ public class StorageServiceImpl
FileStorage fileStorage = fileStorageService.getFileStorage(req.getCode());
fileStorageList.remove(fileStorage);
fileStorage.close();
this.registerResource(MapUtil.of(URLUtil.url(req.getDomain()).getPath(), req.getBucketName()), true);
SpringUtils.deRegisterResourceHandler(MapUtil.of(URLUtil.url(req.getDomain()).getPath(), req.getBucketName()));
}
/**
@ -201,43 +196,4 @@ public class StorageServiceImpl
private boolean isCodeExists(String code, Long id) {
return baseMapper.lambdaQuery().eq(StorageDO::getCode, code).ne(null != id, StorageDO::getId, id).exists();
}
/**
* 注册静态资源映射
*
* @param registerMapping
* 静态资源映射列表
* @param isCancelRegister
* 是否取消注册映射
*/
private void registerResource(Map<String, String> registerMapping, boolean isCancelRegister) {
final UrlPathHelper urlPathHelper = applicationContext.getBean("mvcUrlPathHelper", UrlPathHelper.class);
final ContentNegotiationManager contentNegotiationManager =
applicationContext.getBean("mvcContentNegotiationManager", ContentNegotiationManager.class);
final ServletContext servletContext = applicationContext.getBean(ServletContext.class);
final HandlerMapping resourceHandlerMapping =
applicationContext.getBean("resourceHandlerMapping", HandlerMapping.class);
// 已经注册的静态资源映射
final Map<String, Object> handlerMap =
(Map<String, Object>)ReflectUtil.getFieldValue(resourceHandlerMapping, "handlerMap");
final ResourceHandlerRegistry resourceHandlerRegistry =
new ResourceHandlerRegistry(applicationContext, servletContext, contentNegotiationManager, urlPathHelper);
// 重新注册相同 Pattern 的静态资源映射
for (Map.Entry<String, String> entry : registerMapping.entrySet()) {
String pathPattern = StrUtil.appendIfMissing(entry.getKey(), StringConstants.PATH_PATTERN);
String resourceLocations = StrUtil.appendIfMissing(entry.getValue(), StringConstants.SLASH);
// 移除之前注册过的相同 Pattern 映射
handlerMap.remove(pathPattern);
if (!isCancelRegister) {
// 重新注册映射
resourceHandlerRegistry.addResourceHandler(pathPattern)
.addResourceLocations("file:" + resourceLocations);
}
}
if (!isCancelRegister) {
final Map<String, ?> additionalUrlMap =
ReflectUtil.<SimpleUrlHandlerMapping>invoke(resourceHandlerRegistry, "getHandlerMapping").getUrlMap();
ReflectUtil.<Void>invoke(resourceHandlerMapping, "registerHandlers", additionalUrlMap);
}
}
}