From d5095359db2ca444cd6390d3b2fb696fc1f175e7 Mon Sep 17 00:00:00 2001 From: slhafzjw Date: Sat, 28 Feb 2026 20:38:09 +0800 Subject: [PATCH] refactor(framework): validate and collect `@Shutdown` hooks during agent registration --- .../api/agent/factory/AgentRegisterFactory.kt | 3 ++ .../context/ShutdownHookCollectorFactory.kt | 44 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/context/ShutdownHookCollectorFactory.kt diff --git a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.kt b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.kt index 8e05ca23..af9c0ed8 100644 --- a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.kt +++ b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.kt @@ -10,6 +10,7 @@ import work.slhaf.partner.api.agent.factory.component.ComponentInjectorFactory import work.slhaf.partner.api.agent.factory.component.ComponentRegisterFactory import work.slhaf.partner.api.agent.factory.config.ConfigLoaderFactory import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext +import work.slhaf.partner.api.agent.factory.context.ShutdownHookCollectorFactory import work.slhaf.partner.api.agent.factory.exception.ExternalModuleLoadFailedException import work.slhaf.partner.api.agent.factory.exception.ExternalModulePathNotExistException import java.io.File @@ -38,6 +39,8 @@ object AgentRegisterFactory { CapabilityInjectorFactory().execute(registerContext) // 7. 执行模块 Init Hook 逻辑 ComponentInitHookExecuteFactory().execute(registerContext) + // 8. 校验并收集 Shutdown Hook 逻辑,并添加至 AgentContext 中 + ShutdownHookCollectorFactory().execute(registerContext) } @JvmStatic diff --git a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/context/ShutdownHookCollectorFactory.kt b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/context/ShutdownHookCollectorFactory.kt new file mode 100644 index 00000000..1ecbbe3d --- /dev/null +++ b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/context/ShutdownHookCollectorFactory.kt @@ -0,0 +1,44 @@ +package work.slhaf.partner.api.agent.factory.context + +import work.slhaf.partner.api.agent.factory.AgentBaseFactory +import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore +import work.slhaf.partner.api.agent.factory.component.annotation.AgentComponent +import work.slhaf.partner.api.agent.factory.component.exception.ModuleCheckException +import work.slhaf.partner.api.agent.util.AgentUtil + +class ShutdownHookCollectorFactory : AgentBaseFactory() { + override fun execute(context: AgentRegisterContext) { + val reflections = context.reflections + val agentContext = context.agentContext + + reflections.getMethodsAnnotatedWith(Shutdown::class.java) + .forEach { method -> + val declaringClass = method.declaringClass + val isAgentComponentRelated = + AgentUtil.isAssignableFromAnnotation(declaringClass, AgentComponent::class.java) + val isCapabilityCoreRelated = + AgentUtil.isAssignableFromAnnotation(declaringClass, CapabilityCore::class.java) + + if (!isAgentComponentRelated && !isCapabilityCoreRelated) { + throw ModuleCheckException( + "@Shutdown 仅能用于 AgentComponent/CapabilityCore 相关类: " + + "${declaringClass.name}#${method.name}" + ) + } + if (method.parameterCount > 0) { + throw ModuleCheckException( + "@Shutdown 标注的方法不能包含形参: " + + "${declaringClass.name}#${method.name}" + ) + } + + val order = method.getAnnotation(Shutdown::class.java).order + val added = agentContext.addShutdownHook(method, order) + if (!added) { + throw ModuleCheckException( + "ShutdownHook 收集失败: ${declaringClass.name}#${method.name}" + ) + } + } + } +}