refactor(framework): add ComponentInjectorFactory for module/additional component injection before capability registration

This commit is contained in:
2026-02-23 21:16:04 +08:00
parent 907bb626f2
commit 542de84640
2 changed files with 94 additions and 1 deletions

View File

@@ -5,6 +5,7 @@ import work.slhaf.partner.api.agent.factory.capability.CapabilityCheckFactory;
import work.slhaf.partner.api.agent.factory.capability.CapabilityInjectFactory; import work.slhaf.partner.api.agent.factory.capability.CapabilityInjectFactory;
import work.slhaf.partner.api.agent.factory.capability.CapabilityRegisterFactory; import work.slhaf.partner.api.agent.factory.capability.CapabilityRegisterFactory;
import work.slhaf.partner.api.agent.factory.component.ComponentAnnotationValidatorFactory; import work.slhaf.partner.api.agent.factory.component.ComponentAnnotationValidatorFactory;
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.component.ComponentRegisterFactory;
import work.slhaf.partner.api.agent.factory.component.ModuleInitHookExecuteFactory; import work.slhaf.partner.api.agent.factory.component.ModuleInitHookExecuteFactory;
import work.slhaf.partner.api.agent.factory.config.ConfigLoaderFactory; import work.slhaf.partner.api.agent.factory.config.ConfigLoaderFactory;
@@ -43,7 +44,9 @@ public class AgentRegisterFactory {
new ComponentAnnotationValidatorFactory().execute(registerContext); new ComponentAnnotationValidatorFactory().execute(registerContext);
//2. 收集所有的 AgentComponent 实例 //2. 收集所有的 AgentComponent 实例
new ComponentRegisterFactory().execute(registerContext); new ComponentRegisterFactory().execute(registerContext);
//3. 加载检查Capability层内容后进行能力层的内容注册 //3. 对模块与额外组件进行模块依赖注入
new ComponentInjectorFactory().execute(registerContext);
//4. 加载检查Capability层内容后进行能力层的内容注册
new CapabilityCheckFactory().execute(registerContext); new CapabilityCheckFactory().execute(registerContext);
new CapabilityRegisterFactory().execute(registerContext); new CapabilityRegisterFactory().execute(registerContext);
//. 先一步注入Capability,避免因前hook逻辑存在针对能力的引用而报错 //. 先一步注入Capability,避免因前hook逻辑存在针对能力的引用而报错

View File

@@ -0,0 +1,90 @@
package work.slhaf.partner.api.agent.factory.component
import work.slhaf.partner.api.agent.factory.AgentBaseFactory
import work.slhaf.partner.api.agent.factory.component.annotation.InjectModule
import work.slhaf.partner.api.agent.factory.component.exception.ModuleInstanceGenerateFailedException
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext
import work.slhaf.partner.api.agent.factory.context.ModuleContextData
import java.lang.reflect.Field
import java.lang.reflect.Modifier
class ComponentInjectorFactory : AgentBaseFactory() {
override fun execute(context: AgentRegisterContext) {
val agentContext = context.agentContext
val moduleContextList = agentContext.modules.values.toList()
val runningModules = moduleContextList
.filterIsInstance<ModuleContextData.Running<*>>()
val subModules = moduleContextList
.filterIsInstance<ModuleContextData.Sub<*>>()
val standaloneModules = moduleContextList
.filterIsInstance<ModuleContextData.Standalone<*>>()
val subInstances = subModules.map { it.instance }
val standaloneInstances = standaloneModules.map { it.instance }
val providersForRunning = subInstances + standaloneInstances
val providersForAdditional = subInstances + standaloneInstances
runningModules.forEach { running ->
injectIntoTarget(running.instance, providersForRunning)
subModules.forEach { it.injectTarget.add(running.instance) }
standaloneModules.forEach { it.injectTarget.add(running.instance) }
}
standaloneModules.forEach { standalone ->
injectIntoTarget(standalone.instance, subInstances)
subModules.forEach { it.injectTarget.add(standalone.instance) }
}
agentContext.additionalComponents.forEach { additional ->
injectIntoTarget(additional, providersForAdditional)
}
}
private fun injectIntoTarget(
target: Any,
providers: List<Any>
) {
collectInjectFields(target::class.java).forEach { field ->
val value = resolveInjectValue(field, providers, target::class.java)
try {
field.isAccessible = true
field.set(target, value)
} catch (e: IllegalAccessException) {
throw ModuleInstanceGenerateFailedException(
"模块注入失败: ${target::class.java.name}#${field.name}",
e
)
}
}
}
private fun resolveInjectValue(field: Field, providers: List<Any>, targetClass: Class<*>): Any {
val matched = providers.filter { field.type.isAssignableFrom(it::class.java) }
if (matched.isEmpty()) {
throw ModuleInstanceGenerateFailedException(
"模块注入失败, 未找到可注入实例: ${targetClass.name}#${field.name} -> ${field.type.name}"
)
}
if (matched.size > 1) {
throw ModuleInstanceGenerateFailedException(
"模块注入失败, 存在多个可注入实例: ${targetClass.name}#${field.name} -> ${field.type.name}"
)
}
return matched.first()
}
private fun collectInjectFields(clazz: Class<*>): List<Field> {
val fields = mutableListOf<Field>()
var current: Class<*>? = clazz
while (current != null && current != Any::class.java) {
current.declaredFields
.filter { it.isAnnotationPresent(InjectModule::class.java) }
.filter { !Modifier.isStatic(it.modifiers) }
.forEach { fields.add(it) }
current = current.superclass
}
return fields
}
}