refactor(framework): replace ModuleInitHookExecuteFactory with Kotlin ComponentInitHookExecuteFactory and drive @Init execution from validated component context

This commit is contained in:
2026-02-23 23:14:45 +08:00
parent 1b164cedf1
commit 379cabe042
5 changed files with 80 additions and 97 deletions

View File

@@ -5,9 +5,9 @@ import work.slhaf.partner.api.agent.factory.capability.CapabilityAnnotationValid
import work.slhaf.partner.api.agent.factory.capability.CapabilityInjectorFactory; 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.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.ComponentInitHookExecuteFactory;
import work.slhaf.partner.api.agent.factory.component.ComponentInjectorFactory; 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.config.ConfigLoaderFactory; 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.AgentRegisterContext;
import work.slhaf.partner.api.agent.factory.exception.ExternalModuleLoadFailedException; import work.slhaf.partner.api.agent.factory.exception.ExternalModuleLoadFailedException;
@@ -52,8 +52,8 @@ public class AgentRegisterFactory {
new CapabilityRegisterFactory().execute(registerContext); new CapabilityRegisterFactory().execute(registerContext);
//6. 将 Capability 实例注入至各个 AgentComponent 中 //6. 将 Capability 实例注入至各个 AgentComponent 中
new CapabilityInjectorFactory().execute(registerContext); new CapabilityInjectorFactory().execute(registerContext);
//. 执行模块PreHook逻辑 //7. 执行模块PreHook逻辑
new ModuleInitHookExecuteFactory().execute(registerContext); new ComponentInitHookExecuteFactory().execute(registerContext);
} }

View File

@@ -12,6 +12,8 @@ import work.slhaf.partner.api.agent.util.AgentUtil
class ComponentAnnotationValidatorFactory : AgentBaseFactory() { class ComponentAnnotationValidatorFactory : AgentBaseFactory() {
override fun execute(context: AgentRegisterContext) { override fun execute(context: AgentRegisterContext) {
val reflections = context.reflections val reflections = context.reflections
val componentFactoryContext = context.componentFactoryContext
componentFactoryContext.initMethodsByDeclaringType.clear()
reflections.getMethodsAnnotatedWith(Init::class.java) reflections.getMethodsAnnotatedWith(Init::class.java)
.forEach { method -> .forEach { method ->
@@ -22,6 +24,10 @@ class ComponentAnnotationValidatorFactory : AgentBaseFactory() {
"${declaringClass.name}#${method.name}" "${declaringClass.name}#${method.name}"
) )
} }
val methods = componentFactoryContext
.initMethodsByDeclaringType
.getOrPut(declaringClass) { LinkedHashSet() }
methods.add(method)
} }
reflections.getFieldsAnnotatedWith(InjectModule::class.java) reflections.getFieldsAnnotatedWith(InjectModule::class.java)

View File

@@ -0,0 +1,66 @@
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.Init
import work.slhaf.partner.api.agent.factory.component.exception.ModuleInitHookExecuteFailedException
import work.slhaf.partner.api.agent.factory.context.AgentContext
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext
import work.slhaf.partner.api.agent.util.AgentUtil.methodSignature
import java.lang.reflect.Method
class ComponentInitHookExecuteFactory : AgentBaseFactory() {
override fun execute(context: AgentRegisterContext) {
val initMethodsByDeclaringType = context.componentFactoryContext.initMethodsByDeclaringType
val targets = buildTargets(context.agentContext)
targets.forEach { target ->
val initMethods = collectInitMethods(target::class.java, initMethodsByDeclaringType)
executeInitMethods(target, initMethods)
}
}
private fun buildTargets(agentContext: AgentContext): List<Any> {
val moduleInstances = agentContext.modules.values.map { it.instance }
return moduleInstances + agentContext.additionalComponents
}
private fun collectInitMethods(
targetType: Class<*>,
initMethodsByDeclaringType: Map<Class<*>, Set<Method>>
): List<Method> {
val methods = LinkedHashSet<Method>()
var current: Class<*>? = targetType
while (current != null && current != Any::class.java) {
initMethodsByDeclaringType[current]?.forEach { methods.add(it) }
current = current.superclass
}
return methods
.sortedBy { it.getAnnotation(Init::class.java)?.order ?: 0 }
}
private fun executeInitMethods(target: Any, initMethods: List<Method>) {
initMethods.forEach { method ->
try {
if (method.parameterCount > 0) {
throw ModuleInitHookExecuteFailedException(
"Init方法不支持参数: ${target::class.java.name}#${methodSignature(method)}"
)
}
method.isAccessible = true
method.invoke(target)
} catch (e: ModuleInitHookExecuteFailedException) {
throw e
} catch (e: Exception) {
throw ModuleInitHookExecuteFailedException(
"模块的init hook方法执行失败! 模块: ${target::class.java.simpleName} 方法签名: ${
methodSignature(
method
)
}",
e
)
}
}
}
}

View File

@@ -1,94 +0,0 @@
package work.slhaf.partner.api.agent.factory.component;
import work.slhaf.partner.api.agent.factory.AgentBaseFactory;
import work.slhaf.partner.api.agent.factory.AgentRegisterFactory;
import work.slhaf.partner.api.agent.factory.component.abstracts.AbstractAgentModule;
import work.slhaf.partner.api.agent.factory.component.annotation.Init;
import work.slhaf.partner.api.agent.factory.component.exception.ModuleInitHookExecuteFailedException;
import work.slhaf.partner.api.agent.factory.component.pojo.BaseMetaModule;
import work.slhaf.partner.api.agent.factory.component.pojo.MetaMethod;
import work.slhaf.partner.api.agent.factory.component.pojo.MetaModule;
import work.slhaf.partner.api.agent.factory.component.pojo.MetaSubModule;
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
import work.slhaf.partner.api.agent.util.AgentUtil;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static work.slhaf.partner.api.agent.util.AgentUtil.collectExtendedClasses;
import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature;
/**
* <h2>Agent启动流程 7</h2>
*
* <p>负责执行初始化hook逻辑即 {@link Init} 注解所在方法</p>
*
* <ol>
* <li>
* <p>{@link ModuleInitHookExecuteFactory#collectInitHookMethods(Class, Class)}</p>
* 分别遍历前置模块拿到的模块列表({@link ModuleInitHookExecuteFactory#moduleList}, {@link ModuleInitHookExecuteFactory#subModuleList}),通过 {@link AgentUtil#collectExtendedClasses(Class, Class)} 收集到当前模块类的继承链上的所有类后,收集其所有带有 {@link Init} 注解的方法
* </li>
* <li>
* <p>{@link ModuleInitHookExecuteFactory#proceedInitMethods(BaseMetaModule, List)}</p>
* 收集好初始化方法后,将通过反射执行该方法,所用实例即为前置模块中收集到的执行模块与子模块的 {@link MetaModule} 与 {@link MetaSubModule} 内容
* </li>
* </ol>
*
* <p>Agent启动流程到此进行完毕。整个工厂执行链中均为针对 {@link AgentRegisterContext} 进行的操作,在 {@link AgentRegisterFactory} 中,将进行最终处理以及将必要内容进行传递。</p>
*/
public class ModuleInitHookExecuteFactory extends AgentBaseFactory {
private List<MetaModule> moduleList;
private List<MetaSubModule> subModuleList;
@Override
protected void setVariables(AgentRegisterContext context) {
ModuleFactoryContext factoryContext = context.getModuleFactoryContext();
moduleList = factoryContext.getAgentModuleList();
subModuleList = factoryContext.getAgentSubModuleList();
}
@Override
protected void run() {
//遍历模块列表,并向上查找@Init注解
for (MetaSubModule metaSubModule : subModuleList) {
List<MetaMethod> initHookMethods = collectInitHookMethods(metaSubModule.getClazz(), AbstractAgentRunningModule.class);
proceedInitMethods(metaSubModule, initHookMethods);
}
for (MetaModule metaModule : moduleList) {
List<MetaMethod> initHookMethods = collectInitHookMethods(metaModule.getClazz(), AbstractAgentSubModule.class);
proceedInitMethods(metaModule, initHookMethods);
}
}
private void proceedInitMethods(BaseMetaModule metaModule, List<MetaMethod> initHookMethods) {
for (MetaMethod metaMethod : initHookMethods) {
try {
metaMethod.getMethod().invoke(metaModule.getInstance());
} catch (IllegalAccessException | InvocationTargetException e) {
throw new ModuleInitHookExecuteFailedException("模块的init hook方法执行失败! 模块: " + metaModule.getClazz().getSimpleName() + " 方法签名: " + methodSignature(metaMethod.getMethod()), e);
}
}
}
private List<MetaMethod> collectInitHookMethods(Class<?> clazz, Class<? extends AbstractAgentModule> target) {
Set<Class<?>> classes = collectExtendedClasses(clazz, target);
return classes.stream()
.map(Class::getDeclaredMethods)
.flatMap(Arrays::stream)
.filter(method -> method.isAnnotationPresent(Init.class))
.map(method -> {
MetaMethod metaMethod = new MetaMethod();
metaMethod.setMethod(method);
metaMethod.setOrder(method.getAnnotation(Init.class).order());
return metaMethod;
})
.sorted(Comparator.comparing(MetaMethod::getOrder))
.collect(Collectors.toList());
}
}

View File

@@ -20,6 +20,7 @@ class AgentRegisterContext(urls: List<URL>) {
val configFactoryContext: ConfigFactoryContext = ConfigFactoryContext() val configFactoryContext: ConfigFactoryContext = ConfigFactoryContext()
val capabilityFactoryContext: CapabilityFactoryContext = CapabilityFactoryContext() val capabilityFactoryContext: CapabilityFactoryContext = CapabilityFactoryContext()
val componentFactoryContext: ComponentFactoryContext = ComponentFactoryContext()
val agentContext: AgentContext = AgentContext val agentContext: AgentContext = AgentContext
} }
@@ -33,3 +34,7 @@ class CapabilityFactoryContext {
val capabilities: MutableSet<Class<*>> = LinkedHashSet() val capabilities: MutableSet<Class<*>> = LinkedHashSet()
val methods: MutableSet<Method> = LinkedHashSet() val methods: MutableSet<Method> = LinkedHashSet()
} }
class ComponentFactoryContext {
val initMethodsByDeclaringType: MutableMap<Class<*>, MutableSet<Method>> = LinkedHashMap()
}