惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
WordPress大学
WordPress大学
小众软件
小众软件
云风的 BLOG
云风的 BLOG
IT之家
IT之家
人人都是产品经理
人人都是产品经理
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
博客园 - 【当耐特】
T
Tailwind CSS Blog
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
宝玉的分享
宝玉的分享
博客园 - Franky
F
Fortinet All Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI
D
Docker
博客园 - 聂微东
C
Check Point Blog
H
Help Net Security

博客园 - 悉野

go编译期接口断言 / 编译期接口检查(compile-time interface assertion / compile-time interface check) Go 的类型断言 ssh连结vmware中ubuntu的共享文件夹 spring一个错误修正 抓安卓日记到文件 注册表删除桌面顽固图标 github买的账号无法拉取代码的解决方法 apk常用命令 java服务器异常处理 ES6 学习难度分层 promise原理 材质, 纹理, shader之间的关系 TCP与UDP区别 javascript中=>与function的区别 javascript中函数解析过程 cocos使用fgui 几种服务注册与发现的区别 mybatis测试 向量点乘与叉乘 unity画布3种渲染模式 go学习笔记10(HTTP) go学习笔记9(TCP) go学习笔记8(反射) c++简单的线程池 operator new 是 C++ 动态内存分配的核心函数,负责分配原始内存,不调用构造函数 C++的定位放置new(Placement new) go学习笔记7(泛型,文件读写,测试) go学习笔记6(协程与channel,select使用,线程安全,异常处理) go学习笔记5(函数,结构体,自定义类型和类别名,接口) go学习笔记4(数组与切片,map,if,switch,for循环)
spring加载冲突问题
悉野 · 2026-06-11 · via 博客园 - 悉野
public interface INpcFunctionExecutor {

    /**
     * 执行功能
     */
    void execute(UserSocket socket, TalkNpcFuncData data);

    /**
     * 获取支持的功能类型
     */
    TalkNpcFunc getSupportedFunc();
}



@Slf4j
@Component
public class TaskExecutor implements INpcFunctionExecutor {

    @Override
    public void execute(UserSocket socket, TalkNpcFuncData data) {
        int taskId = Integer.parseInt(data.getFuncParam());
        EventDispatcher.getInstance().fireEvent(
                new TalkChoseEvent(EventType.TALK_CHOSE, socket.getRole(),
                        data.getNpcId(), taskId)
        );
        log.info("触发任务功能: roleId={}, npcId={}, taskId={}",
                socket.getRole().getId(), data.getNpcId(), taskId);
    }

    @Override
    public TalkNpcFunc getSupportedFunc() {
        return TalkNpcFunc.Task;
    }
}


@Slf4j
@Component
public class NpcFunctionExecutorDispatcher {

    private final Map<TalkNpcFunc, INpcFunctionExecutor> executors = new EnumMap<>(TalkNpcFunc.class);

    @Autowired(required = false)
    private List<INpcFunctionExecutor> executorList;

    @PostConstruct
    public void init() {
        // 这儿初始时没能加载TaskExecutor
        if (executorList != null) {
            for (INpcFunctionExecutor executor : executorList) {
                executors.put(executor.getSupportedFunc(), executor);
                log.info("注册NPC功能执行器: {} -> {}",
                        executor.getSupportedFunc(), executor.getClass().getSimpleName());
            }
        }
    }

    /**
     * 执行功能
     * @return 是否找到并执行了执行器
     */
    public boolean dispatch(UserSocket socket, TalkNpcFuncData data) {
        int funcId = data.funcId;
        TalkNpcFunc func = TalkNpcFunc.fromId(funcId);

        INpcFunctionExecutor executor = executors.get(func);
        if (executor != null) {
            try {
                executor.execute(socket, data);
                log.debug("执行NPC功能: func={}, npcId={}", func, data.getNpcId());
                return true;
            } catch (Exception e) {
                log.error("执行NPC功能失败: func={}, npcId={}", func, data.getNpcId(), e);
                return false;
            }
        }

        log.warn("未找到对应的功能执行器: funcId={}, func={}", funcId, func);
        return false;
    }
}

在spring boot下面 些处没能自动加载TaskExecutor

原因:allow-bean-definition-overriding: true 导致 Spring Boot 的 taskExecutor bean 覆盖了 NPC 的 TaskExecutor。

原因:application.yml 里开了 spring.main.allow-bean-definition-overriding: true,而 @Component 的 TaskExecutor 默认 bean 名是 taskExecutor,与 Spring Boot 自带的异步 taskExecutor 重名,被后者静默覆盖,所以不会出现在 List<INpcFunctionExecutor> 里。