Skip to content

Commit

Permalink
refactor: 优化本地存储库注册
Browse files Browse the repository at this point in the history
  • Loading branch information
Charles7c committed Jan 5, 2024
1 parent 635de6b commit 918e897
Showing 1 changed file with 12 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,20 @@

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;

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;

Expand All @@ -55,6 +46,7 @@
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;
Expand All @@ -74,7 +66,6 @@ public class StorageServiceImpl

@Resource
private FileService fileService;
private final ApplicationContext applicationContext;
private final FileStorageService fileStorageService;

@Override
Expand All @@ -89,20 +80,24 @@ public Long add(StorageReq req) {

@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);
}

Expand Down Expand Up @@ -145,7 +140,7 @@ public void load(StorageReq req) {
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();
Expand Down Expand Up @@ -174,7 +169,7 @@ public void unload(StorageReq req) {
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()));
}

/**
Expand All @@ -201,43 +196,4 @@ private boolean isDefaultExists(Long id) {
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);
}
}
}

0 comments on commit 918e897

Please sign in to comment.