news 2026/2/5 23:59:37

Apache Fesod 读取端的事件驱动架构

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Apache Fesod 读取端的事件驱动架构

抽丝剥茧:Apache Fesod 读取端的事件驱动架构

1. 入口:一个优雅的门面 (Facade)

简约而不简单

哪怕系统内部再复杂,给用户的入口必须足够简单。Fesod 采用了经典的Facade 模式(外观模式)。
所有的读取操作都从FesodSheet.read()开始。

// 你的代码FesodSheet.read(file,DemoData.class,listener).sheet().doRead();

这就好比你去餐厅点菜,你只需要跟服务员(Facade)说“来份宫保鸡丁”,你不需要知道后厨的采购员、切菜工、炒菜师傅(Internal Classes)是怎么配合的。

核心类关系

让我们透视一下这个“门面”背后的指挥系统:

从图中可以看到,ExcelReader只是个传话筒,真正的指挥官是ExcelAnalyser,而真正的干活主力是ExcelReadExecutor


2. 流程拆解:一次doRead()的奇幻漂流

当你按下回车调用doRead()时,数据在 Fesod 内部经历了一场接力赛。这场比赛可以分为三个阶段。

第一阶段:智能调度 (Dispatcher)

谁在干活?ExcelAnalyserImpl
职责:看人下菜碟(路由选择)。
核心逻辑
Excel 有两种格式:古老的.xls(BIFF8) 和现代的.xlsx(OOXML ZIP)。
ExcelAnalyserImpl不会盲目解析,它会先偷看文件的前几个字节(Magic Number)或者尝试用 POI 的POIFSFileSystem去探测。

  • 如果是.xls-> 实例化XlsSaxAnalyser
  • 如果是.xlsx-> 实例化XlsxSaxAnalyser
  • 如果是.csv-> 实例化CsvExcelReadExecutor

这就像老司机,听一下发动机声音就知道该挂什么档。

第二阶段:SAX 解析 (Parsing)

谁在干活?XlsxSaxAnalyser(继承自 DefaultHandler)
职责:把 XML 变成事件流。
核心逻辑
这是最“硬核”的部分。Excel 的.xlsx本质上是一堆 XML 文件的压缩包。
Fesod 直接利用 SAX 解析器去读sharedStrings.xml(存字典)和sheet1.xml(存数据)。
它只关心三个事件:

  1. StartElement(<c r="A1">): 哟,一个新的单元格来了,记下它的坐标。
  2. Characters(123): 读到了内容,把它存到临时变量里。
  3. EndElement(</row>): 一行结束了!赶紧把这行数据打包,准备发货。

这种流式处理 (Streaming)意味着,无论你的 Excel 有 100 万行还是 1000 万行,Fesod 内存里永远只有“当前这一行”的数据。

第三阶段:转换与回调 (Converting & Callback)

谁在干活?Converter体系 和ReadListener
职责:把“生数据”变成“熟对象”。
核心逻辑
SAX 读出来的都是 String。但你的 Java Bean 里写的是DateDouble
这时analysisContext里的转换器登场了。它会自动匹配:

  • “这个格子是日期格式,内容是 44567?那我把它转成2022-01-06。”
  • “这个格子是数字?转成Double。”

转换完成后,完整的 Java 对象被构建出来,通过listener.invoke(data)回调给用户的代码。用户处理完这行数据(比如存库),Fesod 就会擦除这行对象的引用,等待 GC 回收。

时序图全景


3. 技术高光:状态的艺术

AnalysisContext (背包客)

在这个复杂的链条中,如何保证状态不丢?
Fesod 设计了一个Context (上下文)对象。它就像一个“背包”,随着流程在各个节点间传递。

  • ReadSheetHolder背在包里:当前解析的是哪个 Sheet?
  • ReadWorkbookHolder背在包里:全局配置是什么?
  • AnalysisContextImpl甚至还维护了当前的行号。

这种设计让各个模块(Analyser, Executor, Converter)都变成了无状态的单例(或者轻量级对象),所有的状态都收敛在 Context 里。这不仅线程安全,而且极易扩展。


4. 总结

Fesod 的读取架构是一次极其标准的事件驱动 (Event-Driven)实践。

  • 它用Dispatcher屏蔽了底层差异。
  • 它用SAX解决了内存瓶颈。
  • 它用Context串联了复杂流程。

当你下一次看着控制台的日志一行行快速滚动,且内存曲线平稳如直线时,请记住:这背后是无数个 XML 事件正在精密地起舞。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/5 20:17:57

用户态/内核态 = 操作系统内核?

用户态/内核态 ≠ 操作系统内核 —— 这是理解操作系统安全与性能的核心概念混淆。 操作系统内核&#xff08;Kernel&#xff09; 是 一段特权代码&#xff0c;负责管理硬件、进程、内存等核心资源用户态&#xff08;User Mode&#xff09; / 内核态&#xff08;Kernel Mode&a…

作者头像 李华
网站建设 2026/2/4 21:57:20

从Vue到Spring Boot:一个Java全栈工程师的实战面试实录

从Vue到Spring Boot&#xff1a;一个Java全栈工程师的实战面试实录 面试开场 面试官&#xff08;王哥&#xff09;&#xff1a;你好&#xff0c;我是王哥&#xff0c;今天来聊聊你对技术的理解和项目经验。先简单介绍一下你自己吧。 应聘者&#xff08;李明&#xff09;&…

作者头像 李华
网站建设 2026/2/5 8:16:33

java项目--智能无人机平台v3pro

项目介绍&#xff1a;再版本三的基础上&#xff0c;新增锁敌功能和攻击功能 代码实现和解释&#xff1a; 【1】更新了isFound函数&#xff0c;新增返回值&#xff08;返回值类型为Intruder&#xff09; 【2】在Drone类中添加goal变量&#xff0c;setgoal方法 public void s…

作者头像 李华
网站建设 2026/2/5 7:15:41

彻底爆了!阿里最新大模型,再次拿下第一!

你好&#xff0c;我是郭震这周末有读者问我&#xff0c;现在解决复杂问题最好的AI模型都有哪些&#xff1f;这篇文章我来给分析总结下这个问题&#xff0c;感兴趣的朋友可以看看这篇文章。大家有没有注意到&#xff0c;现在的大模型发展趋势正在从“拼参数”转向“拼逻辑”。简…

作者头像 李华
网站建设 2026/2/5 4:35:05

社会网络仿真软件:Gephi_(18).社会网络分析理论基础

[[# 社会网络分析理论基础 社会网络的基本概念 社会网络是指个体或组织之间的社会关系构成的网络结构。这些社会关系可以是多种多样的&#xff0c;包括但不限于友谊、合作、通讯、交易等。社会网络分析&#xff08;Social Network Analysis, SNA&#xff09;是一种研究社会网…

作者头像 李华
网站建设 2026/2/5 18:30:58

ES6新增了哪些新特性

1. let/const 声明变量(彻底替代 var) 解决var的变量提升、没有块级作用域、可重复声明三大问题,是 ES6 最基础也是最必须的特性。 let:声明可变的块级作用域变量,不可重复声明,无变量提升(暂时性死区); const:声明不可变的块级作用域常量,必须初始化,不可重复声明…

作者头像 李华