diff --git a/.idea/misc.xml b/.idea/misc.xml index 33abddf0..f01d6df0 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,16 +1,18 @@ - - - - - - - - - - + + + + + + + + + + + + diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.java index bccfa344..d84da9cd 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/AgentRegisterFactory.java @@ -48,7 +48,7 @@ public class AgentRegisterFactory { //. 执行模块PreHook逻辑 new ModuleInitHookExecuteFactory().execute(registerContext); - List moduleList = registerContext.getModuleFactoryContext().getModuleList(); + List moduleList = registerContext.getModuleFactoryContext().getAgentModuleList(); AgentConfigManager.INSTANCE.moduleEnabledStatusFilterAndRecord(moduleList); BeanUtil.copyProperties(registerContext, AgentContext.INSTANCE); diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/context/ModuleFactoryContext.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/context/ModuleFactoryContext.java index 0311215f..14feb990 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/context/ModuleFactoryContext.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/context/ModuleFactoryContext.java @@ -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 moduleList = new ArrayList<>(); + private List agentModuleList = new ArrayList<>(); + private List agentSubModuleList = new ArrayList<>(); } diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleCheckFactory.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleCheckFactory.java index c8eccff5..d33fea20 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleCheckFactory.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleCheckFactory.java @@ -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 methods = reflections.getMethodsAnnotatedWith(Init.class); - Set> types = methods.stream() - .map(Method::getDeclaringClass) - .collect(Collectors.toSet()); + Set> types = getMethodAnnotationTypeSet(AgentModule.class,reflections); checkLocation(types); } diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleInitHookExecuteFactory.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleInitHookExecuteFactory.java index b3c67da5..0c11923d 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleInitHookExecuteFactory.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleInitHookExecuteFactory.java @@ -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 moduleList; + private List 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 initHookMethods = collectInitHookMethods(metaModule.getClazz()); proceedInitMethods(metaModule, initHookMethods); } + + for (MetaSubModule metaSubModule : subModuleList) { + List initHookMethods = collectInitHookMethods(metaSubModule.getClazz()); + proceedInitMethods(metaSubModule, initHookMethods); + } } - private void proceedInitMethods(MetaModule metaModule, List initHookMethods) { + private void proceedInitMethods(BaseMetaModule metaModule, List 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); } } } diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleProxyFactory.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleProxyFactory.java index a53c737f..0ad84991 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleProxyFactory.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleProxyFactory.java @@ -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 moduleList; + private List subModuleList; + private Reflections reflections; + private final HashMap, Object> subModuleInstances = new HashMap<>(); + private final HashMap, 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 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 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 clazz = metaModule.getClazz(); + Class clazz = module.getClazz(); Class 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 clazz = metaModule.getClazz(); + Class 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 clazz = module.getClazz(); + AgentRunningSubModule instance = clazz.getConstructor().newInstance(); + module.setInstance(instance); + subModuleInstances.put(module.getClazz(), instance); } catch (Exception e) { throw new ModuleInstanceGenerateFailedException("模块实例构造失败:" + e.getMessage()); } diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleRegisterFactory.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleRegisterFactory.java index 0a6df073..d8b15660 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleRegisterFactory.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/ModuleRegisterFactory.java @@ -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 moduleList; + private List 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> subModules = reflections.getTypesAnnotatedWith(AgentSubModule.class); + for (Class subModule : subModules) { + if (!ClassUtil.isNormalClass(subModule)) { + continue; + } + Class 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)); } + } diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/annotation/AgentModule.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/annotation/AgentModule.java index d318a1c0..3afd4da1 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/annotation/AgentModule.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/annotation/AgentModule.java @@ -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 { /** diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/annotation/AgentSubModule.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/annotation/AgentSubModule.java new file mode 100644 index 00000000..eddf7461 --- /dev/null +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/annotation/AgentSubModule.java @@ -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 { +} diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/annotation/InjectModule.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/annotation/InjectModule.java new file mode 100644 index 00000000..42754970 --- /dev/null +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/annotation/InjectModule.java @@ -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 { +} diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/pojo/BaseMetaModule.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/pojo/BaseMetaModule.java new file mode 100644 index 00000000..7a1fde7f --- /dev/null +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/pojo/BaseMetaModule.java @@ -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 { + private Class clazz; + private C instance; +} diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/pojo/MetaModule.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/pojo/MetaModule.java index fcb5babe..deac1bcc 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/pojo/MetaModule.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/pojo/MetaModule.java @@ -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{ private String name; private int order; - private Class clazz; - private AgentRunningModule instance; private boolean enabled = true; } diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/pojo/MetaSubModule.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/pojo/MetaSubModule.java new file mode 100644 index 00000000..9ccdd11f --- /dev/null +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/factory/module/pojo/MetaSubModule.java @@ -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{ +} diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/AgentRunningSubModule.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/AgentRunningSubModule.java index 6ca84847..037c604a 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/AgentRunningSubModule.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/AgentRunningSubModule.java @@ -1,12 +1,6 @@ package work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts; -/** - * 流程子模块基类 - * - * @param 输入类型 - * @param 输出类型 - */ public abstract class AgentRunningSubModule extends Module { public abstract O execute(I data); diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/Module.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/Module.java index d6921543..1db91965 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/Module.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/Module.java @@ -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 diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/util/AgentUtil.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/util/AgentUtil.java index 57999b7f..2d64a4f0 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/util/AgentUtil.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/util/AgentUtil.java @@ -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> getMethodAnnotationTypeSet(Class clazz, Reflections reflections){ + Set methods = reflections.getMethodsAnnotatedWith(Init.class); + return methods.stream() + .map(Method::getDeclaringClass) + .collect(Collectors.toSet()); + } + private static void collectInterfaces(Class clazz, Set> classes) { for (Class type : clazz.getInterfaces()) { if (classes.add(type)) { collectInterfaces(type, classes); } } - }} + } +}