进行 Partner 框架层的部分调整

- 新增 AgentSubModule 注解,用于标识子模块
- 新增 MetaSubModule 类,用于存储子模块元信息
- 支持子模块初始化和注入逻辑,不再使用单例模式为执行模块提供子模块服务
- 重构模块初始化流程,支持模块和子模块的初始化
- 优化模块注册流程,分别处理模块和子模块
This commit is contained in:
2025-09-11 13:07:48 +08:00
parent 47684c78e0
commit c1018d6b54
16 changed files with 173 additions and 50 deletions

View File

@@ -48,7 +48,7 @@ public class AgentRegisterFactory {
//. 执行模块PreHook逻辑
new ModuleInitHookExecuteFactory().execute(registerContext);
List<MetaModule> moduleList = registerContext.getModuleFactoryContext().getModuleList();
List<MetaModule> moduleList = registerContext.getModuleFactoryContext().getAgentModuleList();
AgentConfigManager.INSTANCE.moduleEnabledStatusFilterAndRecord(moduleList);
BeanUtil.copyProperties(registerContext, AgentContext.INSTANCE);

View File

@@ -2,11 +2,15 @@ package work.slhaf.partner.api.agent.factory.context;
import lombok.Data;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaSubModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import java.util.ArrayList;
import java.util.List;
@Data
public class ModuleFactoryContext {
private List<MetaModule> moduleList = new ArrayList<>();
private List<MetaModule> agentModuleList = new ArrayList<>();
private List<MetaSubModule> agentSubModuleList = new ArrayList<>();
}

View File

@@ -19,6 +19,8 @@ import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import static work.slhaf.partner.api.agent.util.AgentUtil.getMethodAnnotationTypeSet;
public class ModuleCheckFactory extends AgentBaseFactory {
private Reflections reflections;
@@ -90,10 +92,7 @@ public class ModuleCheckFactory extends AgentBaseFactory {
}
private void initHookLocationCheck() {
Set<Method> methods = reflections.getMethodsAnnotatedWith(Init.class);
Set<Class<?>> types = methods.stream()
.map(Method::getDeclaringClass)
.collect(Collectors.toSet());
Set<Class<?>> types = getMethodAnnotationTypeSet(AgentModule.class,reflections);
checkLocation(types);
}

View File

@@ -5,15 +5,14 @@ import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
import work.slhaf.partner.api.agent.factory.context.ModuleFactoryContext;
import work.slhaf.partner.api.agent.factory.module.annotation.Init;
import work.slhaf.partner.api.agent.factory.module.exception.ModuleInitHookExecuteFailedException;
import work.slhaf.partner.api.agent.factory.module.pojo.BaseMetaModule;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaMethod;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaSubModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import static work.slhaf.partner.api.agent.util.AgentUtil.collectExtendedClasses;
@@ -25,28 +24,35 @@ import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature;
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.getModuleList();
moduleList = factoryContext.getAgentModuleList();
subModuleList = factoryContext.getAgentSubModuleList();
}
@Override
protected void run() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
protected void run() {
//遍历模块列表,并向上查找@Init注解
for (MetaModule metaModule : moduleList) {
List<MetaMethod> initHookMethods = collectInitHookMethods(metaModule.getClazz());
proceedInitMethods(metaModule, initHookMethods);
}
for (MetaSubModule metaSubModule : subModuleList) {
List<MetaMethod> initHookMethods = collectInitHookMethods(metaSubModule.getClazz());
proceedInitMethods(metaSubModule, initHookMethods);
}
}
private void proceedInitMethods(MetaModule metaModule, List<MetaMethod> 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.getName() + " 方法签名: " + methodSignature(metaMethod.getMethod()), e);
throw new ModuleInitHookExecuteFailedException("模块的init hook方法执行失败! 模块: " + metaModule.getClazz().getSimpleName() + " 方法签名: " + methodSignature(metaMethod.getMethod()), e);
}
}
}

View File

@@ -4,17 +4,23 @@ import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.*;
import net.bytebuddy.matcher.ElementMatchers;
import org.reflections.Reflections;
import work.slhaf.partner.api.agent.factory.AgentBaseFactory;
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
import work.slhaf.partner.api.agent.factory.context.ModuleFactoryContext;
import work.slhaf.partner.api.agent.factory.module.annotation.AfterExecute;
import work.slhaf.partner.api.agent.factory.module.annotation.BeforeExecute;
import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule;
import work.slhaf.partner.api.agent.factory.module.exception.ModuleInstanceGenerateFailedException;
import work.slhaf.partner.api.agent.factory.module.exception.ModuleProxyGenerateFailedException;
import work.slhaf.partner.api.agent.factory.module.pojo.BaseMetaModule;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaMethod;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaSubModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
@@ -29,21 +35,46 @@ import static work.slhaf.partner.api.agent.util.AgentUtil.collectExtendedClasses
public class ModuleProxyFactory extends AgentBaseFactory {
private List<MetaModule> moduleList;
private List<MetaSubModule> subModuleList;
private Reflections reflections;
private final HashMap<Class<?>, Object> subModuleInstances = new HashMap<>();
private final HashMap<Class<?>, Object> moduleInstances = new HashMap<>();
@Override
protected void setVariables(AgentRegisterContext context) {
ModuleFactoryContext factoryContext = context.getModuleFactoryContext();
moduleList = factoryContext.getModuleList();
moduleList = factoryContext.getAgentModuleList();
subModuleList = factoryContext.getAgentSubModuleList();
reflections = context.getReflections();
}
@Override
protected void run() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
protected void run() {
generateInstances();
setHookProxy();
createProxy();
injectSubModule();
}
private void setHookProxy() {
for (MetaModule module : moduleList) {
private void injectSubModule() {
Set<Field> fields = reflections.getFieldsAnnotatedWith(InjectModule.class);
try {
for (Field field : fields) {
field.setAccessible(true);
field.set(moduleInstances.get(field.getDeclaringClass()), subModuleInstances.get(field.getType()));
}
} catch (Exception e) {
throw new ModuleInstanceGenerateFailedException("模块实例注入失败", e);
}
}
private void createProxy() {
generateModuleProxy(moduleList);
generateModuleProxy(subModuleList);
}
private void generateModuleProxy(List<? extends BaseMetaModule> list) {
for (BaseMetaModule module : list) {
Class<?> clazz = module.getClazz();
try {
MethodsListRecord record = collectHookMethods(clazz);
@@ -55,9 +86,9 @@ public class ModuleProxyFactory extends AgentBaseFactory {
}
}
private void generateProxiedInstances(MethodsListRecord record, MetaModule metaModule) {
private void generateProxiedInstances(MethodsListRecord record, BaseMetaModule module) {
try {
Class<? extends AgentRunningModule> clazz = metaModule.getClazz();
Class<? extends AgentRunningModule> clazz = module.getClazz();
Class<? extends AgentRunningModule> proxyClass = new ByteBuddy()
.subclass(clazz)
.method(ElementMatchers.isOverriddenFrom(AgentRunningModule.class))
@@ -65,9 +96,9 @@ public class ModuleProxyFactory extends AgentBaseFactory {
.make()
.load(ModuleProxyFactory.class.getClassLoader())
.getLoaded();
metaModule.setInstance(proxyClass.getConstructor().newInstance());
module.setInstance(proxyClass.getConstructor().newInstance());
} catch (Exception e) {
throw new ModuleProxyGenerateFailedException("模块Hook代理生成失败! 代理失败的模块名: " + metaModule.getClazz().getSimpleName(), e);
throw new ModuleProxyGenerateFailedException("模块Hook代理生成失败! 代理失败的模块名: " + module.getClazz().getSimpleName(), e);
}
}
@@ -135,11 +166,23 @@ public class ModuleProxyFactory extends AgentBaseFactory {
}
private void generateInstances() {
for (MetaModule metaModule : moduleList) {
for (MetaModule module : moduleList) {
try {
Class<? extends AgentRunningModule> clazz = metaModule.getClazz();
Class<? extends AgentRunningModule> clazz = module.getClazz();
AgentRunningModule instance = clazz.getConstructor().newInstance();
metaModule.setInstance(instance);
module.setInstance(instance);
moduleInstances.put(module.getClazz(), instance);
} catch (Exception e) {
throw new ModuleInstanceGenerateFailedException("模块实例构造失败:" + e.getMessage());
}
}
for (MetaSubModule module : subModuleList) {
try {
Class<? extends AgentRunningSubModule> clazz = module.getClazz();
AgentRunningSubModule instance = clazz.getConstructor().newInstance();
module.setInstance(instance);
subModuleInstances.put(module.getClazz(), instance);
} catch (Exception e) {
throw new ModuleInstanceGenerateFailedException("模块实例构造失败:" + e.getMessage());
}

View File

@@ -6,8 +6,11 @@ import work.slhaf.partner.api.agent.factory.AgentBaseFactory;
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
import work.slhaf.partner.api.agent.factory.context.ModuleFactoryContext;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaSubModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import java.util.Comparator;
import java.util.List;
@@ -20,17 +23,33 @@ public class ModuleRegisterFactory extends AgentBaseFactory {
private Reflections reflections;
private List<MetaModule> moduleList;
private List<MetaSubModule> subModuleList;
@Override
protected void setVariables(AgentRegisterContext context) {
ModuleFactoryContext factoryContext = context.getModuleFactoryContext();
reflections = context.getReflections();
moduleList = factoryContext.getModuleList();
moduleList = factoryContext.getAgentModuleList();
subModuleList = factoryContext.getAgentSubModuleList();
}
@Override
protected void run() {
setModuleList();
setSubModuleList();
}
private void setSubModuleList() {
Set<Class<?>> subModules = reflections.getTypesAnnotatedWith(AgentSubModule.class);
for (Class<?> subModule : subModules) {
if (!ClassUtil.isNormalClass(subModule)) {
continue;
}
Class<? extends AgentRunningSubModule> clazz = subModule.asSubclass(AgentRunningSubModule.class);
MetaSubModule metaSubModule = new MetaSubModule();
metaSubModule.setClazz(clazz);
subModuleList.add(metaSubModule);
}
}
private void setModuleList() {
@@ -50,4 +69,5 @@ public class ModuleRegisterFactory extends AgentBaseFactory {
}
moduleList.sort(Comparator.comparing(MetaModule::getOrder));
}
}

View File

@@ -1,14 +1,16 @@
package work.slhaf.partner.api.agent.factory.module.annotation;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityHolder;
import java.lang.annotation.*;
/**
* 用于注解执行模块
*/
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@CapabilityHolder
public @interface AgentModule {
/**

View File

@@ -0,0 +1,11 @@
package work.slhaf.partner.api.agent.factory.module.annotation;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityHolder;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@CapabilityHolder
public @interface AgentSubModule {
}

View File

@@ -0,0 +1,11 @@
package work.slhaf.partner.api.agent.factory.module.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectModule {
}

View File

@@ -0,0 +1,11 @@
package work.slhaf.partner.api.agent.factory.module.pojo;
import lombok.Data;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.Module;
@Data
public abstract class BaseMetaModule <C extends Module> {
private Class<? extends C> clazz;
private C instance;
}

View File

@@ -1,13 +1,13 @@
package work.slhaf.partner.api.agent.factory.module.pojo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
@EqualsAndHashCode(callSuper = true)
@Data
public class MetaModule {
public class MetaModule extends BaseMetaModule<AgentRunningModule>{
private String name;
private int order;
private Class<? extends AgentRunningModule> clazz;
private AgentRunningModule instance;
private boolean enabled = true;
}

View File

@@ -0,0 +1,10 @@
package work.slhaf.partner.api.agent.factory.module.pojo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
@EqualsAndHashCode(callSuper = true)
@Data
public class MetaSubModule extends BaseMetaModule<AgentRunningSubModule>{
}

View File

@@ -1,12 +1,6 @@
package work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts;
/**
* 流程子模块基类
*
* @param <I> 输入类型
* @param <O> 输出类型
*/
public abstract class AgentRunningSubModule<I, O> extends Module {
public abstract O execute(I data);

View File

@@ -2,13 +2,11 @@ package work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts;
import lombok.Getter;
import lombok.Setter;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityHolder;
import work.slhaf.partner.api.agent.runtime.interaction.flow.entity.Model;
/**
* 模块基类
*/
@CapabilityHolder
public abstract class Module {
@Getter

View File

@@ -1,8 +1,12 @@
package work.slhaf.partner.api.agent.util;
import org.reflections.Reflections;
import work.slhaf.partner.api.agent.factory.module.annotation.Init;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
public final class AgentUtil {
@@ -36,10 +40,18 @@ public final class AgentUtil {
collectInterfaces(clazz, classes);
}
public static Set<Class<?>> getMethodAnnotationTypeSet(Class<?> clazz, Reflections reflections){
Set<Method> methods = reflections.getMethodsAnnotatedWith(Init.class);
return methods.stream()
.map(Method::getDeclaringClass)
.collect(Collectors.toSet());
}
private static void collectInterfaces(Class<?> clazz, Set<Class<?>> classes) {
for (Class<?> type : clazz.getInterfaces()) {
if (classes.add(type)) {
collectInterfaces(type, classes);
}
}
}}
}
}