langchain4j @ApiService实现原理
整体一句话概括
AiServicesAutoConfig 这是 LangChain4j 整合 Spring 的自动配置类,核心依靠BeanFactoryPostProcessor,自动扫描所有加了
@AiService的 AI 接口,删掉原生接口的 Bean 定义、重新注册AiServiceFactory工厂 Bean,自动装配 ChatModel、记忆、工具、RAG 等 AI 组件,不用手动创建 AI 服务代理。分步完整拆解(逻辑从头到尾闭环)
1、入口:注册 BeanFactoryPostProcessor(核心钩子)
- 容器启动阶段,所有 Bean 实例化之前执行这个后置处理器(也就是你之前问的 BeanFactoryPostProcessor 阶段);
- 此时容器只有 BeanDefinition(类的元数据,还没创建对象),可以随意新增、删除、修改 Bean 定义;
- 整个 AI 服务自动注册逻辑全部写在这个后置处理器回调内部。
2、第一步:提前收集 Spring 容器里所有 AI 依赖组件
先把 Spring 中所有可用 AI 相关 Bean 全部查出来,存成数组备用:
- ChatModel / StreamingChatModel:普通 / 流式大模型
- ChatMemory / ChatMemoryProvider:对话记忆、记忆提供器
- ContentRetriever / RetrievalAugmentor:RAG 检索器、完整检索增强器
- ModerationModel:内容审核模型
同时遍历容器全部 Bean,扫描所有带
@Tool注解的方法,收集工具名称、生成工具描述ToolSpecification,后面自动注入给 AI 服务。3、第二步:扫描项目所有标注 @AiService 的接口
找到你代码里所有写了
@AiService的 AI 交互接口(比如@AiService interface Assistant{}),循环逐个处理每一个 AI 接口。对每个 @AiService 接口的改造逻辑(重点,修改 BeanDefinition)
- 拿到当前 AI 接口原始的 BeanDefinition(Spring 扫描接口自动生成的原始定义);
- 新建 GenericBeanDefinition,把 BeanClass 改成
AiServiceFactory(工厂 Bean,专门生成 AI 接口代理对象); - 把原始 AI 接口 Class 作为构造参数传给工厂,让工厂知道要代理哪个接口;
- 读取接口上
@AiService注解配置,自动填充所有 AI 组件依赖:1)EXPLICIT 显式模式:用户在注解手动指定 Bean 名称,直接引用用户写的 model/memory/retriever; 2)AUTOMATIC 自动模式:容器中该类型只有 1 个 Bean 就自动注入;存在多个同类型 Bean 直接抛冲突异常,提示用户手动指定;两种装配模式 wiringMode
- 处理 Tool 工具集合:
- EXPLICIT:只用注解里手动声明的工具;
- AUTOMATIC:自动把容器全部带
@Tool的 Bean 全部注入 AI 服务;
4、替换原始接口的 Bean 定义(关键操作,修改 BeanDefinition)
- 删除 Spring 自动扫描出来的、原始 AI 接口的 BeanDefinition;
- 注册我们刚刚构建好、绑定了 AiServiceFactory 的新 BeanDefinition;
- Bean 名称统一首字母小写,遵循 Spring Bean 命名规范。
对应你之前纠结的 BeanDefinition 问题
- 第一步:Spring 扫描接口生成原始 BeanDefinition;
- BeanFactoryPostProcessor 执行阶段:删除旧定义、注册全新的工厂 BeanDefinition;
- 后面实例化 Bean 时,使用的是全新构建的 AiServiceFactory 的 BeanDefinition,内容完全不一样。
5、发布事件,完成收尾
替换注册完成后,发布
AiServiceRegisteredEvent事件,外部可以监听这个事件,感知 AI 服务注册完成,做扩展逻辑。配套工具方法作用(辅助逻辑)
addBeanReference:统一封装依赖装配逻辑,区分自动 / 显式模式,注入 RuntimeBeanReference(延迟 Bean 引用,避免提前实例化);conflict:多同类型 Bean 冲突时抛出友好提示异常;toManagedList:Spring 专用集合 ManagedList,用来存放工具 Bean 的引用,兼容 BeanDefinition 解析;lowercaseFirstLetter:规范 Bean 名称首字母小写。
6、运行时最终效果(闭环收尾)
等 BeanFactoryPostProcessor 执行完毕后,容器进入普通 Bean 生命周期:
- 实例化
AiServiceFactory这个 FactoryBean; - 填充我们刚刚配置好的 ChatModel、记忆、RAG、Tool 全部属性;
- 初始化完成后,FactoryBean 调用
getObject(),动态生成 AI 接口的代理实现类; - 业务代码中
@Autowired Assistant assistant注入的就是这个代理对象,直接调用方法就能和大模型交互。
核心价值总结
不用自己手动创建 AiService.builder () 组装大模型、记忆、工具、RAG;
只要给接口加
@AiService,Spring 自动完成全部依赖装配、代理创建,自动适配容器内已有的 AI 组件,简化 LangChain4j 在 Spring 项目的开发。
浙公网安备 33010602011771号