refactor(framework): migrate CapabilityRegisterFactory to Kotlin and rebuild capability registration from validated context

This commit is contained in:
2026-02-23 22:32:32 +08:00
parent e0a62053b5
commit 2e29e5ca7f
4 changed files with 144 additions and 210 deletions

View File

@@ -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);

View File

@@ -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;
/**
* <h2>Agent启动流程 5</h2>
*
* <p>
* 负责收集注解 {@link Capability} 和 {@link CapabilityCore} 标识的类并生成函数路由表、创建core、capability实例以及放入instanceMap供后续进行注入操作
* </p>
*
* <ol>
* <li>
* <p>{@link CapabilityRegisterFactory#setCoreInstances()}</p>
* 通过反射调用无参构造函数创建core实例并将实例放入instanceMap供后续使用
* </li>
* <li>
* <p>{@link CapabilityRegisterFactory#generateRouterTable()}</p>
* 生成函数路由表:
* <ul>
* <li>
* <p>{@link CapabilityRegisterFactory#generateMethodsRouterTable()}</p>
* 生成普通方法对应的函数路由表
* </li>
* <li>
* <p>{@link CapabilityRegisterFactory#generateCoordinatedMethodsRouterTable()}</p>
* 生成协调方法对应的函数路由表
* </li>
* </ul>
* </li>
* <li>
* 函数路由表生成完毕、core实例创建完毕之后将交由下一工厂完成能力(Capability)注入操作,注入到 {@link AgentRunningModule} 与 {@link AgentSubModule} 对应的实例中
* </li>
* </ol>
*
* <p>下一步流程请参阅{@link CapabilityInjectFactory}</p>
*/
public class CapabilityRegisterFactory extends AgentBaseFactory {
private Reflections reflections;
private HashMap<String, Function<Object[], Object>> methodsRouterTable;
private HashMap<String, Function<Object[], Object>> coordinatedMethodsRouterTable;
private HashMap<Class<?>, Object> coreInstances;
private HashMap<Class<?>, Object> capabilityHolderInstances;
private Set<Class<?>> cores;
private Set<Class<?>> 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<Class<?>> 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<Method> methodsAnnotatedWith = reflections.getMethodsAnnotatedWith(Coordinated.class);
if (methodsAnnotatedWith.isEmpty()) {
return;
}
try {
//获取所有CM实例
HashMap<String, Object> coordinateManagerInstances = getCoordinateManagerInstances();
methodsAnnotatedWith.forEach(method -> {
String key = method.getAnnotation(Coordinated.class).capability() + "." + methodSignature(method);
Function<Object[], Object> 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);
}
}
/**
* 获取<code>CoordinateManager</code>子类实例
*/
private HashMap<String, Object> getCoordinateManagerInstances() throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
HashMap<String, Object> 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<Object[], Object> 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);
}));
}
/**
* 反射获取<code>CapabilityCore</code>实例
*/
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实例创建失败");
}
}
}

View File

@@ -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<Class<*>, Any>()
val methodsRouterTable = LinkedHashMap<String, Function<Array<Any?>, 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<Class<*>>,
coreInstances: MutableMap<Class<*>, 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<Class<*>>,
coreInstances: Map<Class<*>, Any>,
methodsRouterTable: MutableMap<String, Function<Array<Any?>, Any?>>
): Map<String, MethodBinding> {
val map = LinkedHashMap<String, MethodBinding>()
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<String, Function<Array<Any?>, 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<Any?>()) as Array<Any?>
fn.apply(actualArgs)
}
}
}
}
private fun buildCapabilityMethodMap(
capabilityType: Class<*>,
capabilityValue: String,
methodBindingMap: Map<String, MethodBinding>
): Map<String, Method> {
val methods = LinkedHashMap<String, Method>()
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?>): 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
)
}

View File

@@ -33,4 +33,3 @@ class CapabilityFactoryContext {
val capabilities: MutableSet<Class<*>> = LinkedHashSet()
val methods: MutableSet<Method> = LinkedHashSet()
}