package com.example.workutils.tool; import com.example.workutils.config.WorkUtilsProperties; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.util.*; import java.util.stream.Collectors; /** * 工具注册中心 * 自动发现Spring容器中的Tool Bean,按配置过滤启用/禁用 */ @Slf4j @Component public class ToolRegistry { private final List allTools; private final WorkUtilsProperties properties; private List enabledTools; private Map toolByIdMap; private Map toolByCommandMap; /** * Spring自动注入所有Tool Bean * 新增工具只需创建@Component类实现Tool接口,无需修改此类 */ public ToolRegistry(List tools, WorkUtilsProperties properties) { this.allTools = tools; this.properties = properties; } @PostConstruct public void init() { Set enabledIds = resolveEnabledIds(); this.enabledTools = new ArrayList<>(); this.toolByIdMap = new LinkedHashMap<>(); this.toolByCommandMap = new LinkedHashMap<>(); for (Tool tool : allTools) { try { if (enabledIds == null || enabledIds.contains(tool.getId())) { enabledTools.add(tool); toolByIdMap.put(tool.getId(), tool); String cmd = tool.getCommandName(); if (cmd != null && !cmd.isEmpty()) { toolByCommandMap.put(cmd, tool); } log.info("注册工具: {} [{}]", tool.getName(), tool.getId()); } else { log.info("跳过已禁用工具: {} [{}]", tool.getName(), tool.getId()); } } catch (Exception e) { // 工具隔离:单个工具初始化异常不影响平台和其他工具 log.error("工具初始化失败: {} [{}]", tool.getName(), tool.getId(), e); } } log.info("工具注册完成: {}/{} 已启用", enabledTools.size(), allTools.size()); } /** * 获取所有已启用工具 */ public List getEnabledTools() { return Collections.unmodifiableList(enabledTools); } /** * 按ID查找工具 */ public Optional getToolById(String id) { return Optional.ofNullable(toolByIdMap.get(id)); } /** * 按命令行命令名查找工具 */ public Optional getToolByCommand(String command) { return Optional.ofNullable(toolByCommandMap.get(command)); } /** * 根据配置解析启用的工具ID集合 * 优先级: enabled白名单 > disabled黑名单 > 全部启用 * * @return null表示全部启用,否则为启用的ID集合 */ private Set resolveEnabledIds() { WorkUtilsProperties.ToolsConfig toolsConfig = properties.getTools(); if (toolsConfig == null) { return null; } if (toolsConfig.getEnabled() != null && !toolsConfig.getEnabled().isEmpty()) { return new HashSet<>(toolsConfig.getEnabled()); } if (toolsConfig.getDisabled() != null && !toolsConfig.getDisabled().isEmpty()) { Set allIds = allTools.stream() .map(Tool::getId) .collect(Collectors.toSet()); allIds.removeAll(toolsConfig.getDisabled()); return allIds; } return null; } }