mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
适配框架时发现工厂注册链上存在一些执行顺序上的错误,于是尝试修复问题,为Agent启动链添加了完整的注释,并做出了必要的修复与调整
This commit is contained in:
@@ -12,6 +12,10 @@ import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* <h2>Agent 启动入口</h2>
|
||||
* 详细启动流程请参阅{@link AgentRegisterFactory}
|
||||
*/
|
||||
public final class Agent {
|
||||
|
||||
public static AgentGatewayStep newAgent(Class<?> clazz) {
|
||||
|
||||
@@ -16,12 +16,20 @@ import work.slhaf.partner.api.agent.factory.module.ModuleRegisterFactory;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.agent.runtime.data.AgentContext;
|
||||
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.AgentRunningFlow;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <h2>Agent 注册工厂</h2>
|
||||
*
|
||||
* <p>
|
||||
* 具体流程依次按照 {@link AgentRegisterFactory#launch(String)} 方法顺序执行,最终将执行模块列表对应实例交给 {@link AgentConfigManager} ,传递给 {@link AgentRunningFlow} 针对交互做出调用
|
||||
* <p/>
|
||||
*/
|
||||
public class AgentRegisterFactory {
|
||||
|
||||
private static final List<URL> urls = new ArrayList<>();
|
||||
@@ -35,14 +43,14 @@ public class AgentRegisterFactory {
|
||||
//流程
|
||||
//0. 加载配置
|
||||
new ConfigLoaderFactory().execute(registerContext);
|
||||
//1. 注册并检查Capability
|
||||
new CapabilityRegisterFactory().execute(registerContext);
|
||||
new CapabilityCheckFactory().execute(registerContext);
|
||||
//2. 注册并检查Module
|
||||
//1. 注册并检查Module
|
||||
new ModuleCheckFactory().execute(registerContext);
|
||||
new ModuleRegisterFactory().execute(registerContext);
|
||||
//3. 为module通过动态代理添加PostHook逻辑并进行实例化
|
||||
//2. 为module通过动态代理添加PostHook逻辑并进行实例化
|
||||
new ModuleProxyFactory().execute(registerContext);
|
||||
//3. 加载检查Capability层内容后进行能力层的内容注册
|
||||
new CapabilityCheckFactory().execute(registerContext);
|
||||
new CapabilityRegisterFactory().execute(registerContext);
|
||||
//. 先一步注入Capability,避免因前hook逻辑存在针对能力的引用而报错
|
||||
new CapabilityInjectFactory().execute(registerContext);
|
||||
//. 执行模块PreHook逻辑
|
||||
|
||||
@@ -9,6 +9,9 @@ import work.slhaf.partner.api.agent.factory.capability.exception.UnMatchedCapabi
|
||||
import work.slhaf.partner.api.agent.factory.capability.exception.UnMatchedCoordinatedMethodException;
|
||||
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
|
||||
import work.slhaf.partner.api.agent.factory.context.CapabilityFactoryContext;
|
||||
import work.slhaf.partner.api.agent.factory.module.ModuleCheckFactory;
|
||||
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.util.AgentUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@@ -18,7 +21,34 @@ import java.util.stream.Collectors;
|
||||
import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature;
|
||||
|
||||
/**
|
||||
* 执行<code>Capability</code>相关检查
|
||||
* <h2>Agent启动流程 4</h2>
|
||||
*
|
||||
* <p>负责通过反射收集 {@link Capability} 和 {@link CapabilityCore} 注解所在类,并判断是否存在被错误忽略的方法</p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* <p>{@link CapabilityCheckFactory#loadCoresAndCapabilities()}</p>
|
||||
* 通过反射收集 {@link Capability} 和 {@link CapabilityCore} 注解所在类为对应集合
|
||||
* </li>
|
||||
* <li>
|
||||
* <p>{@link CapabilityCheckFactory#checkCountAndCapabilities()}</p>
|
||||
* 检测 {@link Capability} 与 {@link CapabilityCore} 的数量、对应的能力是否相等。每一个core都将对应一个capability,并通过value属性进行匹配
|
||||
* </li>
|
||||
* <li>
|
||||
* <p>{@link CapabilityCheckFactory#checkCapabilityMethods()}</p>
|
||||
* 检测在 {@link Capability} 与 {@link CapabilityCore} 中是否存在对方尚未实现/注册的方法
|
||||
* </li>
|
||||
* <li>
|
||||
* <p>{@link CapabilityCheckFactory#checkCoordinatedMethods()}</p>
|
||||
* 检查是否包含协调方法({@link ToCoordinated}),如果存在,则进一步检查在 {@link CoordinateManager} 所注类中是否有提供对应的实现
|
||||
* </li>
|
||||
* <li>
|
||||
* <p>{@link CapabilityCheckFactory#checkInjectCapability()}</p>
|
||||
* 检查 {@link InjectCapability} 注解是否只用在 {@link CapabilityHolder} 所标识类的字段上。{@link AgentModule} 与 {@link AgentSubModule} 已经被 {@link CapabilityHolder} 标注
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>下一步流程请参阅{@link CapabilityRegisterFactory}</p>
|
||||
*/
|
||||
public class CapabilityCheckFactory extends AgentBaseFactory {
|
||||
|
||||
@@ -37,12 +67,18 @@ public class CapabilityCheckFactory extends AgentBaseFactory {
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
loadCoresAndCapabilities();
|
||||
checkCountAndCapabilities();
|
||||
checkCapabilityMethods();
|
||||
checkCoordinatedMethods();
|
||||
checkInjectCapability();
|
||||
}
|
||||
|
||||
private void loadCoresAndCapabilities() {
|
||||
cores.addAll(reflections.getTypesAnnotatedWith(CapabilityCore.class));
|
||||
capabilities.addAll(reflections.getTypesAnnotatedWith(Capability.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查<code>@InjectCapability</code>注解是否只用在<code>@CapabilityHolder</code>所标识类的字段上
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,9 @@ import work.slhaf.partner.api.agent.factory.capability.annotation.ToCoordinated;
|
||||
import work.slhaf.partner.api.agent.factory.capability.exception.ProxySetFailedExceptionCapability;
|
||||
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
|
||||
import work.slhaf.partner.api.agent.factory.context.CapabilityFactoryContext;
|
||||
import work.slhaf.partner.api.agent.factory.module.ModuleInitHookExecuteFactory;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Proxy;
|
||||
@@ -18,9 +21,23 @@ import java.util.function.Function;
|
||||
import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature;
|
||||
|
||||
/**
|
||||
* 负责执行<code>Capability</code>的注入逻辑
|
||||
*/
|
||||
public class CapabilityInjectFactory extends AgentBaseFactory {
|
||||
* <h2>Agent启动流程 6</h2>
|
||||
*
|
||||
* <p>负责执行 {@link Capability} 的注入逻辑。</p>
|
||||
*
|
||||
* <p>实现方式:</p>
|
||||
* <ol>
|
||||
* <li>通过动态代理,为 {@link AgentModule} 与 {@link AgentSubModule} 中待注入的
|
||||
* <b>能力接口</b> 类型(即 {@link Capability} 标注的接口类)生成代理对象。
|
||||
* </li>
|
||||
* <li>在代理对象内部,根据调用方法的签名确定路由,将调用转发至对应的具体函数。
|
||||
* </li>
|
||||
* <li>通过此机制,实现了 {@link Capability} 单一语义层面上普通方法与协调方法的统一入口。
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>下一步流程请参阅 {@link ModuleInitHookExecuteFactory}</p>
|
||||
*/public class CapabilityInjectFactory extends AgentBaseFactory {
|
||||
|
||||
private Reflections reflections;
|
||||
private HashMap<String, Function<Object[], Object>> coordinatedMethodsRouterTable;
|
||||
|
||||
@@ -8,6 +8,8 @@ import work.slhaf.partner.api.agent.factory.capability.exception.CoreInstancesCr
|
||||
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.factory.context.CapabilityFactoryContext;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -17,19 +19,48 @@ import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static cn.hutool.core.util.ClassUtil.isNormalClass;
|
||||
import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature;
|
||||
|
||||
|
||||
/**
|
||||
* 负责获取<code>@Capability</code>和<code>@CapabilityCore</code>标识的类,并生成函数路由表、设置<code>Core</code>实例用于后续注入
|
||||
* <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 AgentModule} 与 {@link AgentSubModule} 对应的实例中
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>下一步流程请参阅{@link CapabilityInjectFactory}</p>
|
||||
*/
|
||||
public final class CapabilityRegisterFactory extends AgentBaseFactory {
|
||||
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> capabilityCoreInstances;
|
||||
private HashMap<Class<?>, Object> coreInstances;
|
||||
private HashMap<Class<?>, Object> capabilityHolderInstances;
|
||||
private Set<Class<?>> cores;
|
||||
private Set<Class<?>> capabilities;
|
||||
@@ -40,38 +71,18 @@ public final class CapabilityRegisterFactory extends AgentBaseFactory {
|
||||
reflections = context.getReflections();
|
||||
methodsRouterTable = factoryContext.getMethodsRouterTable();
|
||||
coordinatedMethodsRouterTable = factoryContext.getCoordinatedMethodsRouterTable();
|
||||
capabilityCoreInstances = factoryContext.getCapabilityCoreInstances();
|
||||
coreInstances = factoryContext.getCapabilityCoreInstances();
|
||||
cores = factoryContext.getCores();
|
||||
capabilities = factoryContext.getCapabilities();
|
||||
capabilityHolderInstances = factoryContext.getCapabilityHolderInstances();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||
setCapabilityCoreInstances();
|
||||
setAnnotatedClasses();
|
||||
protected void run() {
|
||||
setCoreInstances();
|
||||
generateRouterTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置<code>CapabilityCore</code>、<code>Capability</code>注解标识类
|
||||
*/
|
||||
private void setAnnotatedClasses() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||
cores.addAll(reflections.getTypesAnnotatedWith(CapabilityCore.class));
|
||||
capabilities.addAll(reflections.getTypesAnnotatedWith(Capability.class));
|
||||
setCapabilityHolderInstances();
|
||||
}
|
||||
|
||||
private void setCapabilityHolderInstances() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
|
||||
for (Class<?> clazz : reflections.getTypesAnnotatedWith(CapabilityHolder.class)) {
|
||||
if (!isNormalClass(clazz)){
|
||||
continue;
|
||||
}
|
||||
Object o = clazz.getDeclaredConstructor().newInstance();
|
||||
capabilityHolderInstances.put(clazz, o);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成函数路由表
|
||||
*/
|
||||
@@ -128,17 +139,16 @@ public final class CapabilityRegisterFactory extends AgentBaseFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成普通方法对应的函数路由表
|
||||
* 扫描`@Capability`与`@CapabilityMethod`注解的类与方法
|
||||
* 将`capabilityValue.methodSignature`作为key,函数对象为通过反射拿到的core实例对应的方法
|
||||
*/
|
||||
private void generateMethodsRouterTable() {
|
||||
//扫描`@Capability`与`@CapabilityMethod`注解的类与方法
|
||||
//将`capabilityValue.methodSignature`作为key,函数对象为通过反射拿到的core实例对应的方法
|
||||
cores.forEach(core -> Arrays.stream(core.getMethods())
|
||||
.filter(method -> method.isAnnotationPresent(CapabilityMethod.class))
|
||||
.forEach(method -> {
|
||||
Function<Object[], Object> function = args -> {
|
||||
try {
|
||||
return method.invoke(capabilityCoreInstances.get(core), args);
|
||||
return method.invoke(coreInstances.get(core), args);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -154,12 +164,12 @@ public final class CapabilityRegisterFactory extends AgentBaseFactory {
|
||||
/**
|
||||
* 反射获取<code>CapabilityCore</code>实例
|
||||
*/
|
||||
private void setCapabilityCoreInstances() {
|
||||
private void setCoreInstances() {
|
||||
try {
|
||||
for (Class<?> core : cores) {
|
||||
Constructor<?> constructor = core.getDeclaredConstructor();
|
||||
constructor.setAccessible(true);
|
||||
capabilityCoreInstances.put(core, constructor.newInstance());
|
||||
coreInstances.put(core, constructor.newInstance());
|
||||
}
|
||||
} catch (InvocationTargetException | NoSuchMethodException | InstantiationException |
|
||||
IllegalAccessException e) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import work.slhaf.partner.api.agent.factory.AgentBaseFactory;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.ModelConfig;
|
||||
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
|
||||
import work.slhaf.partner.api.agent.factory.context.ConfigFactoryContext;
|
||||
import work.slhaf.partner.api.agent.factory.module.ModuleCheckFactory;
|
||||
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
|
||||
import work.slhaf.partner.api.agent.runtime.config.FileAgentConfigManager;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
@@ -11,6 +12,14 @@ import work.slhaf.partner.api.chat.pojo.Message;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <h2>Agent启动流程 0</h2>
|
||||
* <p>
|
||||
* 通过指定的 {@link AgentConfigManager} 或者默认的 {@link FileAgentConfigManager} 加载配置文件
|
||||
* <p/>
|
||||
*
|
||||
* <p>下一步流程请参阅{@link ModuleCheckFactory}</p>
|
||||
*/
|
||||
public class ConfigLoaderFactory extends AgentBaseFactory {
|
||||
|
||||
private AgentConfigManager agentConfigManager;
|
||||
@@ -23,7 +32,7 @@ public class ConfigLoaderFactory extends AgentBaseFactory {
|
||||
modelConfigMap = factoryContext.getModelConfigMap();
|
||||
modelPromptMap = factoryContext.getModelPromptMap();
|
||||
|
||||
if (AgentConfigManager.INSTANCE == null){
|
||||
if (AgentConfigManager.INSTANCE == null) {
|
||||
AgentConfigManager.setINSTANCE(new FileAgentConfigManager());
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,7 @@ 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.context.AgentRegisterContext;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AfterExecute;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.BeforeExecute;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.Init;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.*;
|
||||
import work.slhaf.partner.api.agent.factory.module.exception.ModuleCheckException;
|
||||
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel;
|
||||
@@ -21,6 +18,30 @@ import java.util.stream.Collectors;
|
||||
|
||||
import static work.slhaf.partner.api.agent.util.AgentUtil.getMethodAnnotationTypeSet;
|
||||
|
||||
/**
|
||||
* <h2>Agent启动流程 1</h2>
|
||||
*
|
||||
* <p>
|
||||
* 检查模块部分抽象类与注解、接口的使用方式
|
||||
* </p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* <p>{@link ModuleCheckFactory#annotationAbstractCheck(Set, Class)}</p>
|
||||
* 所有添加了 {@link AgentModule} 注解的类都将作为Agent的执行模块,为规范模块入口,都必须实现抽象类: {@link AgentRunningModule}; {@link AgentSubModule} 注解所在类则必须实现 {@link AgentRunningSubModule}
|
||||
* </li>
|
||||
* <li>
|
||||
* <p>{@link ModuleCheckFactory#moduleConstructorsCheck(Set)}</p>
|
||||
* 所有 {@link AgentModule} 与 {@link AgentSubModule} 注解所在类都必须具备空参构造方法,初始化逻辑可放在 @Init 注解所处方法中,将在 Capability 与 subModules 注入后才会执行
|
||||
* </li>
|
||||
* <li>
|
||||
* <p>{@link ModuleCheckFactory#activateModelImplCheck()}</p>
|
||||
* 检查实现了 {@link ActivateModel} 的模块数量、名称与prompt是否一致
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>下一步流程请参阅{@link ModuleRegisterFactory}</p>
|
||||
*/
|
||||
public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
|
||||
private Reflections reflections;
|
||||
@@ -32,13 +53,14 @@ public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
Set<Class<?>> types = reflections.getTypesAnnotatedWith(AgentModule.class);
|
||||
//检查注解AgentModule所在类是否继承了AgentInteractionModule
|
||||
agentModuleAnnotationCheck(types);
|
||||
Set<Class<?>> moduleTypes = reflections.getTypesAnnotatedWith(AgentModule.class);
|
||||
Set<Class<?>> subModuleTypes = reflections.getTypesAnnotatedWith(AgentSubModule.class);
|
||||
//检查注解AgentModule或AgentSubModule所在类是否继承了对应的抽象类
|
||||
annotationAbstractCheck(moduleTypes, AgentRunningModule.class);
|
||||
annotationAbstractCheck(subModuleTypes, AgentRunningSubModule.class);
|
||||
//检查AgentModule是否具备无参构造方法
|
||||
moduleConstructorsCheck(types);
|
||||
//检查hook注解所在方法是否位于AgentInteractionModule子类/AgentInteractionSubModule子类/ActivateModel子类
|
||||
hookLocationCheck();
|
||||
moduleConstructorsCheck(moduleTypes);
|
||||
moduleConstructorsCheck(subModuleTypes);
|
||||
//检查实现了ActivateModel的模块数量、名称与prompt是否一致
|
||||
activateModelImplCheck();
|
||||
}
|
||||
@@ -92,7 +114,7 @@ public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
}
|
||||
|
||||
private void initHookLocationCheck() {
|
||||
Set<Class<?>> types = getMethodAnnotationTypeSet(AgentModule.class,reflections);
|
||||
Set<Class<?>> types = getMethodAnnotationTypeSet(AgentModule.class, reflections);
|
||||
checkLocation(types);
|
||||
}
|
||||
|
||||
@@ -128,12 +150,12 @@ public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private void agentModuleAnnotationCheck(Set<Class<?>> types) {
|
||||
private void annotationAbstractCheck(Set<Class<?>> types, Class<?> clazz) {
|
||||
for (Class<?> type : types) {
|
||||
if (type.isAnnotation()) {
|
||||
continue;
|
||||
}
|
||||
if (AgentRunningModule.class.isAssignableFrom(type) && ClassUtil.isNormalClass(type)) {
|
||||
if (clazz.isAssignableFrom(type) && ClassUtil.isNormalClass(type)) {
|
||||
continue;
|
||||
}
|
||||
throw new ModuleCheckException("存在未继承AgentInteractionModule.class的AgentModule实现: " + type.getSimpleName());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package work.slhaf.partner.api.agent.factory.module;
|
||||
|
||||
import work.slhaf.partner.api.agent.factory.AgentBaseFactory;
|
||||
import work.slhaf.partner.api.agent.factory.AgentRegisterFactory;
|
||||
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;
|
||||
@@ -10,6 +11,7 @@ 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.util.AgentUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
@@ -19,7 +21,22 @@ import static work.slhaf.partner.api.agent.util.AgentUtil.collectExtendedClasses
|
||||
import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature;
|
||||
|
||||
/**
|
||||
* 负责执行前hook逻辑
|
||||
* <h2>Agent启动流程 7</h2>
|
||||
*
|
||||
* <p>负责执行初始化hook逻辑,即 {@link Init} 注解所在方法</p>
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* <p>{@link ModuleInitHookExecuteFactory#collectInitHookMethods(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 {
|
||||
|
||||
@@ -36,15 +53,15 @@ public class ModuleInitHookExecuteFactory extends AgentBaseFactory {
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
for (MetaModule metaModule : moduleList) {
|
||||
List<MetaMethod> initHookMethods = collectInitHookMethods(metaModule.getClazz());
|
||||
proceedInitMethods(metaModule, initHookMethods);
|
||||
}
|
||||
}
|
||||
|
||||
private void proceedInitMethods(BaseMetaModule metaModule, List<MetaMethod> initHookMethods) {
|
||||
|
||||
@@ -4,9 +4,10 @@ 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.capability.CapabilityCheckFactory;
|
||||
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
|
||||
import work.slhaf.partner.api.agent.factory.context.CapabilityFactoryContext;
|
||||
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;
|
||||
@@ -18,10 +19,9 @@ 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 work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.Module;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -30,46 +30,85 @@ import java.util.stream.Collectors;
|
||||
import static work.slhaf.partner.api.agent.util.AgentUtil.collectExtendedClasses;
|
||||
|
||||
/**
|
||||
* 通过扫描注解<code>@BeforeExecute</code>,获取到各个模块的后hook逻辑并通过动态代理添加到执行逻辑之后
|
||||
* <h2>Agent启动流程 3</h2>
|
||||
*
|
||||
* <p>
|
||||
* 扫描前置模块各个hook注解生成代理对象,放入对应的list中并按照类型为键放入 {@link ModuleProxyFactory#capabilityHolderInstances} 中供后续完成能力(capability)注入
|
||||
* <p/>
|
||||
*
|
||||
* <ol>
|
||||
*
|
||||
* <li>
|
||||
* <p>{@link ModuleProxyFactory#createProxiedInstances()}</p>
|
||||
* 根据moduleList中的类型信息,向上查找继承链获取所有hook方法收集为{@link MethodsListRecord},然后通过ByteBuddy根据收集到的preHook与postHook生成代理对象,放入对应的 {@link MetaModule} 对象以及 instanceMap 中
|
||||
* </li>
|
||||
* <li>
|
||||
* <p>{@link ModuleProxyFactory#injectSubModule()}</p>
|
||||
* 通过反射将子模块实例注入到执行模块中带有注解 {@link InjectModule} 的字段
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>下一步流程请参阅{@link CapabilityCheckFactory}</p>
|
||||
*/
|
||||
public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
|
||||
private List<MetaModule> moduleList;
|
||||
private List<MetaSubModule> subModuleList;
|
||||
private Reflections reflections;
|
||||
private HashMap<Class<?>, Object> capabilityHolderInstances;
|
||||
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();
|
||||
CapabilityFactoryContext capabilityFactoryContext = context.getCapabilityFactoryContext();
|
||||
moduleList = factoryContext.getAgentModuleList();
|
||||
subModuleList = factoryContext.getAgentSubModuleList();
|
||||
reflections = context.getReflections();
|
||||
capabilityHolderInstances = capabilityFactoryContext.getCapabilityHolderInstances();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
generateInstances();
|
||||
createProxy();
|
||||
createProxiedInstances();
|
||||
injectSubModule();
|
||||
}
|
||||
|
||||
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);
|
||||
for (MetaModule module : moduleList) {
|
||||
Arrays.stream(module.getClazz().getFields())
|
||||
.filter(field -> field.isAnnotationPresent(InjectModule.class))
|
||||
.forEach(field -> {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
field.set(
|
||||
moduleInstances.get(module.getClazz()),
|
||||
subModuleInstances.get(field.getType())
|
||||
);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ModuleInstanceGenerateFailedException("模块实例注入失败", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createProxy() {
|
||||
private void createProxiedInstances() {
|
||||
generateModuleProxy(moduleList);
|
||||
generateModuleProxy(subModuleList);
|
||||
updateInstanceMap(moduleInstances, moduleList);
|
||||
updateInstanceMap(subModuleInstances, subModuleList);
|
||||
updateCapabilityHolderInstances();
|
||||
}
|
||||
|
||||
private void updateCapabilityHolderInstances() {
|
||||
capabilityHolderInstances.putAll(moduleInstances);
|
||||
capabilityHolderInstances.putAll(subModuleInstances);
|
||||
}
|
||||
|
||||
private void updateInstanceMap(HashMap<Class<?>, Object> instanceMap, List<? extends BaseMetaModule> list) {
|
||||
for (BaseMetaModule baseMetaModule : list) {
|
||||
instanceMap.put(baseMetaModule.getClazz(), baseMetaModule.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,8 +127,8 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
|
||||
private void generateProxiedInstances(MethodsListRecord record, BaseMetaModule module) {
|
||||
try {
|
||||
Class<? extends AgentRunningModule> clazz = module.getClazz();
|
||||
Class<? extends AgentRunningModule> proxyClass = new ByteBuddy()
|
||||
Class<? extends Module> clazz = module.getClazz();
|
||||
Class<? extends Module> proxyClass = new ByteBuddy()
|
||||
.subclass(clazz)
|
||||
.method(ElementMatchers.isOverriddenFrom(AgentRunningModule.class))
|
||||
.intercept(MethodDelegation.to(new ModuleProxyInterceptor(record.post, record.pre)))
|
||||
@@ -165,30 +204,6 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateInstances() {
|
||||
for (MetaModule module : moduleList) {
|
||||
try {
|
||||
Class<? extends AgentRunningModule> clazz = module.getClazz();
|
||||
AgentRunningModule instance = clazz.getConstructor().newInstance();
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private record ModuleProxyInterceptor(List<MetaMethod> postHookMethods, List<MetaMethod> preHookMethods) {
|
||||
@RuntimeType
|
||||
public Object intercept(@Origin Method method, @AllArguments Object[] allArguments, @SuperCall Callable<?> zuper, @This Object proxy) throws Exception {
|
||||
|
||||
@@ -17,7 +17,27 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 负责扫描<code>@Module</code>注解获取模块实例
|
||||
* <h2>Agent启动流程 2</h2>
|
||||
*
|
||||
* <p>
|
||||
* 负责收集 {@link AgentModule} 与 {@link AgentSubModule} 注解所在类的信息,供后续工厂完成动态代理、模块与能力注入
|
||||
* <p/>
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* <p>{@link ModuleRegisterFactory#setModuleList()}</p>
|
||||
* 扫描 {@link AgentModule} 注解,获取执行模块信息: 类型、模块名称({@link AgentModule#name()}),执行顺序。并按照注解的 {@link AgentModule#order()} 字段进行排序
|
||||
* </li>
|
||||
* <li>
|
||||
* <p>{@link ModuleRegisterFactory#setSubModuleList()}</p>
|
||||
* 扫描 {@link AgentSubModule} 注册,获取子模块类型信息
|
||||
* </li>
|
||||
* <li>
|
||||
* 两种模块都将存入各自的list中,供后续模块完成注册与注入
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>下一步流程请参阅{@link ModuleProxyFactory}</p>
|
||||
*/
|
||||
public class ModuleRegisterFactory extends AgentBaseFactory {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user