From 2e29e5ca7f4830ff6d7de2959f945c5ed383abb6 Mon Sep 17 00:00:00 2001 From: slhafzjw Date: Mon, 23 Feb 2026 22:32:32 +0800 Subject: [PATCH] refactor(framework): migrate `CapabilityRegisterFactory` to Kotlin and rebuild capability registration from validated context --- .../agent/factory/AgentRegisterFactory.java | 1 + .../capability/CapabilityRegisterFactory.java | 209 ------------------ .../capability/CapabilityRegisterFactory.kt | 143 ++++++++++++ .../factory/context/AgentRegisterContext.kt | 1 - 4 files changed, 144 insertions(+), 210 deletions(-) delete mode 100644 Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityRegisterFactory.java create mode 100644 Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityRegisterFactory.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 6047e4c4..3a341de8 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 @@ -48,6 +48,7 @@ public class AgentRegisterFactory { new ComponentInjectorFactory().execute(registerContext); //4. 加载检查Capability层内容后进行能力层的内容注册 new CapabilityAnnotationValidatorFactory().execute(registerContext); + //5. 根据 Capability 相关的扫描结果构造 Capability 实例 new CapabilityRegisterFactory().execute(registerContext); //. 先一步注入Capability,避免因前hook逻辑存在针对能力的引用而报错 new CapabilityInjectFactory().execute(registerContext); diff --git a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityRegisterFactory.java b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityRegisterFactory.java deleted file mode 100644 index 8b47b6bb..00000000 --- a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityRegisterFactory.java +++ /dev/null @@ -1,209 +0,0 @@ -package work.slhaf.partner.api.agent.factory.capability; - -import cn.hutool.core.util.ClassUtil; -import org.reflections.Reflections; -import work.slhaf.partner.api.agent.factory.AgentBaseFactory; -import work.slhaf.partner.api.agent.factory.capability.annotation.*; -import work.slhaf.partner.api.agent.factory.capability.exception.CapabilityCoreInstancesCreateFailedException; -import work.slhaf.partner.api.agent.factory.capability.exception.CapabilityFactoryExecuteFailedException; -import work.slhaf.partner.api.agent.factory.capability.exception.DuplicateMethodException; -import work.slhaf.partner.api.agent.factory.component.annotation.AgentComponent; -import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - -import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature; - - -/** - *

Agent启动流程 5

- * - *

- * 负责收集注解 {@link Capability} 和 {@link CapabilityCore} 标识的类,并生成函数路由表、创建core、capability实例,以及放入instanceMap供后续进行注入操作 - *

- * - *
    - *
  1. - *

    {@link CapabilityRegisterFactory#setCoreInstances()}

    - * 通过反射调用无参构造函数创建core实例,并将实例放入instanceMap供后续使用 - *
  2. - *
  3. - *

    {@link CapabilityRegisterFactory#generateRouterTable()}

    - * 生成函数路由表: - *
      - *
    • - *

      {@link CapabilityRegisterFactory#generateMethodsRouterTable()}

      - * 生成普通方法对应的函数路由表 - *
    • - *
    • - *

      {@link CapabilityRegisterFactory#generateCoordinatedMethodsRouterTable()}

      - * 生成协调方法对应的函数路由表 - *
    • - *
    - *
  4. - *
  5. - * 函数路由表生成完毕、core实例创建完毕之后,将交由下一工厂完成能力(Capability)注入操作,注入到 {@link AgentRunningModule} 与 {@link AgentSubModule} 对应的实例中 - *
  6. - *
- * - *

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

- */ -public class CapabilityRegisterFactory extends AgentBaseFactory { - - private Reflections reflections; - private HashMap> methodsRouterTable; - private HashMap> coordinatedMethodsRouterTable; - private HashMap, Object> coreInstances; - private HashMap, Object> capabilityHolderInstances; - private Set> cores; - private Set> capabilities; - - @Override - protected void setVariables(AgentRegisterContext context) { - CapabilityFactoryContext factoryContext = context.getCapabilityFactoryContext(); - reflections = context.getReflections(); - methodsRouterTable = factoryContext.getMethodsRouterTable(); - coordinatedMethodsRouterTable = factoryContext.getCoordinatedMethodsRouterTable(); - coreInstances = factoryContext.getCapabilityCoreInstances(); - cores = factoryContext.getCores(); - capabilities = factoryContext.getCapabilities(); - capabilityHolderInstances = factoryContext.getCapabilityHolderInstances(); - } - - @Override - protected void run() { - setCapabilityHolderInstances(); - setCoreInstances(); - generateRouterTable(); - } - - private void setCapabilityHolderInstances() { - Set> collect = reflections.getTypesAnnotatedWith(AgentComponent.class).stream() - .filter(ClassUtil::isNormalClass) - .filter(clazz -> !capabilityHolderInstances.containsKey(clazz)) - .collect(Collectors.toSet()); - for (Class clazz : collect) { - try { - Constructor constructor = clazz.getDeclaredConstructor(); - if (constructor.canAccess(null)) { - throw new CapabilityFactoryExecuteFailedException("缺少无参构造方法的类: " + clazz); - } - Object o = constructor.newInstance(); - capabilityHolderInstances.put(clazz, o); - } catch (Exception e) { - throw new CapabilityFactoryExecuteFailedException("创建代理对象失败: " + clazz, e); - } - } - } - - /** - * 生成函数路由表 - */ - private void generateRouterTable() { - generateMethodsRouterTable(); - generateCoordinatedMethodsRouterTable(); - } - - /** - * 生成协调函数对应的函数路由表 - */ - private void generateCoordinatedMethodsRouterTable() { - Set methodsAnnotatedWith = reflections.getMethodsAnnotatedWith(Coordinated.class); - if (methodsAnnotatedWith.isEmpty()) { - return; - } - try { - //获取所有CM实例 - HashMap coordinateManagerInstances = getCoordinateManagerInstances(); - methodsAnnotatedWith.forEach(method -> { - String key = method.getAnnotation(Coordinated.class).capability() + "." + methodSignature(method); - Function function = args -> { - try { - return method.invoke(coordinateManagerInstances.get(key), args); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - }; - coordinatedMethodsRouterTable.put(key, function); - }); - } catch (Exception e) { - throw new CapabilityFactoryExecuteFailedException("创建协调方法路由表出错", e); - } - - } - - /** - * 获取CoordinateManager子类实例 - */ - private HashMap getCoordinateManagerInstances() throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException { - HashMap map = new HashMap<>(); - for (Class c : reflections.getTypesAnnotatedWith(CoordinateManager.class)) { - Constructor constructor = c.getDeclaredConstructor(); - Object instance = constructor.newInstance(); - setCores(instance, c); - Arrays.stream(c.getMethods()) - .filter(method -> method.isAnnotationPresent(Coordinated.class)) - .forEach(method -> { - String key = method.getAnnotation(Coordinated.class).capability() + "." + methodSignature(method); - map.put(key, instance); - }); - } - return map; - } - - private void setCores(Object cmInstance, Class cmClazz) throws IllegalAccessException { - for (Field field : cmClazz.getFields()) { - if (field.getType().isAnnotationPresent(CapabilityCore.class)) { - field.setAccessible(true); - field.set(cmInstance, coreInstances.get(field.getType())); - } - } - } - - /** - * 扫描`@Capability`与`@CapabilityMethod`注解的类与方法 - * 将`capabilityValue.methodSignature`作为key,函数对象为通过反射拿到的core实例对应的方法 - */ - private void generateMethodsRouterTable() { - cores.forEach(core -> Arrays.stream(core.getMethods()) - .filter(method -> method.isAnnotationPresent(CapabilityMethod.class)) - .forEach(method -> { - Function function = args -> { - try { - return method.invoke(coreInstances.get(core), args); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - }; - String key = core.getAnnotation(CapabilityCore.class).value() + "." + methodSignature(method); - if (methodsRouterTable.containsKey(key)) { - throw new DuplicateMethodException("重复注册能力方法: " + core.getPackage().getName() + "." + core.getSimpleName() + "#" + method.getName()); - } - methodsRouterTable.put(key, function); - })); - } - - /** - * 反射获取CapabilityCore实例 - */ - private void setCoreInstances() { - try { - for (Class core : cores) { - Constructor constructor = core.getDeclaredConstructor(); - constructor.setAccessible(true); - coreInstances.put(core, constructor.newInstance()); - } - } catch (InvocationTargetException | NoSuchMethodException | InstantiationException | - IllegalAccessException e) { - throw new CapabilityCoreInstancesCreateFailedException("core实例创建失败"); - } - } -} diff --git a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityRegisterFactory.kt b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityRegisterFactory.kt new file mode 100644 index 00000000..56e54be7 --- /dev/null +++ b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/capability/CapabilityRegisterFactory.kt @@ -0,0 +1,143 @@ +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.CapabilityCore +import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod +import work.slhaf.partner.api.agent.factory.capability.exception.CapabilityCoreInstancesCreateFailedException +import work.slhaf.partner.api.agent.factory.capability.exception.CapabilityFactoryExecuteFailedException +import work.slhaf.partner.api.agent.factory.capability.exception.DuplicateMethodException +import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext +import work.slhaf.partner.api.agent.util.AgentUtil.methodSignature +import java.lang.reflect.Method +import java.lang.reflect.Proxy +import java.util.function.Function + +class CapabilityRegisterFactory : AgentBaseFactory() { + override fun execute(context: AgentRegisterContext) { + val capabilityFactoryContext = context.capabilityFactoryContext + val agentContext = context.agentContext + + val cores = capabilityFactoryContext.cores.toSet() + val capabilities = capabilityFactoryContext.capabilities.toSet() + if (cores.isEmpty() || capabilities.isEmpty()) { + throw CapabilityFactoryExecuteFailedException("CapabilityFactoryContext 中缺少已校验的 capability/core 信息") + } + + val coreInstances = LinkedHashMap, Any>() + val methodsRouterTable = LinkedHashMap, Any?>>() + + setCoreInstances(cores, coreInstances) + val methodBindingMap = buildMethodBindingMap(cores, coreInstances, methodsRouterTable) + + capabilities.forEach { capabilityType -> + val capabilityValue = capabilityType.getAnnotation(Capability::class.java).value + val proxy = createCapabilityProxy(capabilityType, capabilityValue, methodsRouterTable) + val methods = buildCapabilityMethodMap(capabilityType, capabilityValue, methodBindingMap) + agentContext.addCapability(capabilityValue, proxy, methods) + } + } + + private fun setCoreInstances( + cores: Set>, + coreInstances: MutableMap, Any> + ) { + try { + cores.forEach { core -> + val constructor = core.getDeclaredConstructor() + constructor.isAccessible = true + coreInstances[core] = constructor.newInstance() + } + } catch (e: Exception) { + throw CapabilityCoreInstancesCreateFailedException("core实例创建失败", e) + } + } + + private fun buildMethodBindingMap( + cores: Set>, + coreInstances: Map, Any>, + methodsRouterTable: MutableMap, Any?>> + ): Map { + val map = LinkedHashMap() + cores.forEach { core -> + val capabilityValue = core.getAnnotation(CapabilityCore::class.java).value + val coreInstance = coreInstances[core] + ?: throw CapabilityFactoryExecuteFailedException("未找到CapabilityCore实例: ${core.name}") + + core.methods + .filter { it.isAnnotationPresent(CapabilityMethod::class.java) } + .forEach { method -> + val key = "$capabilityValue.${methodSignature(method)}" + if (map.containsKey(key) || methodsRouterTable.containsKey(key)) { + throw DuplicateMethodException("重复注册能力方法: ${core.name}#${method.name}") + } + map[key] = MethodBinding(core, coreInstance, method) + methodsRouterTable[key] = Function { args -> + invokeMethod(coreInstance, method, args) + } + } + } + return map + } + + private fun createCapabilityProxy( + capabilityType: Class<*>, + capabilityValue: String, + methodsRouterTable: Map, Any?>> + ): Any { + return Proxy.newProxyInstance( + capabilityType.classLoader, + arrayOf(capabilityType) + ) { proxy, method, args -> + when (method.name) { + "toString" -> "CapabilityProxy($capabilityValue)" + "hashCode" -> System.identityHashCode(proxy) + "equals" -> proxy === args?.firstOrNull() + else -> { + val key = "$capabilityValue.${methodSignature(method)}" + val fn = methodsRouterTable[key] + ?: throw CapabilityFactoryExecuteFailedException("未找到能力方法路由: $key") + + @Suppress("UNCHECKED_CAST") + val actualArgs = (args ?: emptyArray()) as Array + fn.apply(actualArgs) + } + } + } + } + + private fun buildCapabilityMethodMap( + capabilityType: Class<*>, + capabilityValue: String, + methodBindingMap: Map + ): Map { + val methods = LinkedHashMap() + capabilityType.methods.forEach { method -> + if (method.declaringClass == Any::class.java) { + return@forEach + } + val key = "$capabilityValue.${methodSignature(method)}" + val binding = methodBindingMap[key] + ?: throw CapabilityFactoryExecuteFailedException("Capability方法缺少实现: $key") + methods[key] = binding.method + } + return methods + } + + private fun invokeMethod(instance: Any, method: Method, args: Array): Any? { + return try { + method.invoke(instance, *args) + } catch (e: Exception) { + throw CapabilityFactoryExecuteFailedException( + "能力方法调用失败: ${instance::class.java.name}#${method.name}", + e + ) + } + } + + private data class MethodBinding( + val coreType: Class<*>, + val instance: Any, + val method: Method + ) +} diff --git a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/context/AgentRegisterContext.kt b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/context/AgentRegisterContext.kt index 0b021ab0..d8831f51 100644 --- a/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/context/AgentRegisterContext.kt +++ b/Partner-Framework/src/main/java/work/slhaf/partner/api/agent/factory/context/AgentRegisterContext.kt @@ -33,4 +33,3 @@ class CapabilityFactoryContext { val capabilities: MutableSet> = LinkedHashSet() val methods: MutableSet = LinkedHashSet() } -