From 1b164cedf1e87bd9d399ba5c2276857e2c1754a3 Mon Sep 17 00:00:00 2001 From: slhafzjw Date: Mon, 23 Feb 2026 22:59:47 +0800 Subject: [PATCH] refactor(framework): migrate capability injection to Kotlin `CapabilityInjectorFactory` and inject capability instances directly into components --- .../agent/factory/AgentRegisterFactory.java | 6 +- .../capability/CapabilityInjectFactory.java | 86 ------------------- .../capability/CapabilityInjectorFactory.kt | 80 +++++++++++++++++ 3 files changed, 83 insertions(+), 89 deletions(-) delete mode 100644 Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityInjectFactory.java create mode 100644 Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityInjectorFactory.kt diff --git a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.java b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.java index 3a341de8..2995f8ef 100644 --- a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.java +++ b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.java @@ -2,7 +2,7 @@ package work.slhaf.partner.api.agent.factory; import org.reflections.util.ClasspathHelper; import work.slhaf.partner.api.agent.factory.capability.CapabilityAnnotationValidatorFactory; -import work.slhaf.partner.api.agent.factory.capability.CapabilityInjectFactory; +import work.slhaf.partner.api.agent.factory.capability.CapabilityInjectorFactory; 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.ComponentInjectorFactory; @@ -50,8 +50,8 @@ public class AgentRegisterFactory { new CapabilityAnnotationValidatorFactory().execute(registerContext); //5. 根据 Capability 相关的扫描结果构造 Capability 实例 new CapabilityRegisterFactory().execute(registerContext); - //. 先一步注入Capability,避免因前hook逻辑存在针对能力的引用而报错 - new CapabilityInjectFactory().execute(registerContext); + //6. 将 Capability 实例注入至各个 AgentComponent 中 + new CapabilityInjectorFactory().execute(registerContext); //. 执行模块PreHook逻辑 new ModuleInitHookExecuteFactory().execute(registerContext); diff --git a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityInjectFactory.java b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityInjectFactory.java deleted file mode 100644 index dd18644e..00000000 --- a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityInjectFactory.java +++ /dev/null @@ -1,86 +0,0 @@ -package work.slhaf.partner.api.agent.factory.capability; - -import org.reflections.Reflections; -import work.slhaf.partner.api.agent.factory.AgentBaseFactory; -import work.slhaf.partner.api.agent.factory.capability.annotation.Capability; -import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; -import work.slhaf.partner.api.agent.factory.capability.annotation.ToCoordinated; -import work.slhaf.partner.api.agent.factory.capability.exception.CapabilityProxySetFailedException; -import work.slhaf.partner.api.agent.factory.component.ModuleInitHookExecuteFactory; -import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext; - -import java.lang.reflect.Field; -import java.lang.reflect.Proxy; -import java.util.HashMap; -import java.util.Set; -import java.util.function.Function; - -import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature; - -/** - *

Agent启动流程 6

- * - *

负责执行 {@link Capability} 的注入逻辑。

- * - *

实现方式:

- *
    - *
  1. 通过动态代理,为 {@link AgentRunningModule} 与 {@link AgentSubModule} 中待注入的 - * 能力接口 类型(即 {@link Capability} 标注的接口类)生成代理对象。 - *
  2. - *
  3. 在代理对象内部,根据调用方法的签名确定路由,将调用转发至对应的具体函数。 - *
  4. - *
  5. 通过此机制,实现了 {@link Capability} 单一语义层面上普通方法与协调方法的统一入口。 - *
  6. - *
- * - *

下一步流程请参阅 {@link ModuleInitHookExecuteFactory}

- */ -public class CapabilityInjectFactory extends AgentBaseFactory { - - private Reflections reflections; - private HashMap> coordinatedMethodsRouterTable; - private HashMap> methodsRouterTable; - private HashMap, Object> capabilityHolderInstances; - - @Override - protected void setVariables(AgentRegisterContext context) { - CapabilityFactoryContext factoryContext = context.getCapabilityFactoryContext(); - reflections = context.getReflections(); - coordinatedMethodsRouterTable = factoryContext.getCoordinatedMethodsRouterTable(); - methodsRouterTable = factoryContext.getMethodsRouterTable(); - capabilityHolderInstances = factoryContext.getCapabilityHolderInstances(); - } - - @Override - protected void run() { - //获取现有的`@InjectCapability`注解所在字段,并获取对应的类,通过动态代理注入对象 - Set fields = reflections.getFieldsAnnotatedWith(InjectCapability.class); - //在动态代理内部,通过函数路由表调用对应的方法 - createProxy(fields); - } - - private void createProxy(Set fields) { - try { - for (Field field : fields) { - field.setAccessible(true); - Class fieldType = field.getType(); - Object instance = Proxy.newProxyInstance( - fieldType.getClassLoader(), - new Class[]{fieldType}, - (proxy, method, objects) -> { - if (method.isAnnotationPresent(ToCoordinated.class)) { - String key = method.getDeclaringClass().getAnnotation(Capability.class).value() + "." + methodSignature(method); - return coordinatedMethodsRouterTable.get(key).apply(objects); - } - String key = fieldType.getAnnotation(Capability.class).value() + "." + methodSignature(method); - return methodsRouterTable.get(key).apply(objects); - } - ); - field.set(capabilityHolderInstances.get(field.getDeclaringClass()), instance); - } - } catch (Exception e) { - throw new CapabilityProxySetFailedException("代理设置失败", e); - } - } - -} diff --git a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityInjectorFactory.kt b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityInjectorFactory.kt new file mode 100644 index 00000000..93eb4244 --- /dev/null +++ b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityInjectorFactory.kt @@ -0,0 +1,80 @@ +package work.slhaf.partner.api.agent.factory.capability + +import work.slhaf.partner.api.agent.factory.AgentBaseFactory +import work.slhaf.partner.api.agent.factory.capability.annotation.Capability +import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability +import work.slhaf.partner.api.agent.factory.capability.exception.CapabilityProxySetFailedException +import work.slhaf.partner.api.agent.factory.context.AgentContext +import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext +import java.lang.reflect.Field +import java.lang.reflect.Modifier + +class CapabilityInjectorFactory : AgentBaseFactory() { + override fun execute(context: AgentRegisterContext) { + val agentContext = context.agentContext + val targets = buildTargets(agentContext) + targets.forEach { target -> + injectCapabilities(target, agentContext.capabilities) + } + } + + private fun buildTargets(agentContext: AgentContext): List { + val moduleInstances = agentContext.modules.values.map { it.instance } + return moduleInstances + agentContext.additionalComponents + } + + private fun injectCapabilities( + target: Any, + capabilityMap: Map + ) { + collectInjectFields(target::class.java).forEach { field -> + try { + field.isAccessible = true + val value = resolveCapabilityInstance(field, capabilityMap, target::class.java) + field.set(target, value) + } catch (e: CapabilityProxySetFailedException) { + throw e + } catch (e: Exception) { + throw CapabilityProxySetFailedException( + "Capability 注入失败: ${target::class.java.name}#${field.name}", + e + ) + } + } + } + + private fun resolveCapabilityInstance( + field: Field, + capabilityMap: Map, + targetClass: Class<*> + ): Any { + val capability = field.type.getAnnotation(Capability::class.java) + ?: throw CapabilityProxySetFailedException( + "InjectCapability 字段类型未标注 @Capability: ${targetClass.name}#${field.name} -> ${field.type.name}" + ) + + val capabilityValue = capability.value + val implementation = capabilityMap[capabilityValue] ?: throw CapabilityProxySetFailedException( + "未找到可注入 Capability 实例: ${targetClass.name}#${field.name} -> $capabilityValue" + ) + if (!field.type.isAssignableFrom(implementation.instance.javaClass)) { + throw CapabilityProxySetFailedException( + "Capability 实例类型不匹配: ${targetClass.name}#${field.name} -> $capabilityValue" + ) + } + return implementation.instance + } + + private fun collectInjectFields(clazz: Class<*>): List { + val fields = mutableListOf() + var current: Class<*>? = clazz + while (current != null && current != Any::class.java) { + current.declaredFields + .filter { it.isAnnotationPresent(InjectCapability::class.java) } + .filter { !Modifier.isStatic(it.modifiers) } + .forEach { fields.add(it) } + current = current.superclass + } + return fields + } +}