Apache OFbiz MiniLang 源码解读

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: MiniLang所有元素的父类——MiniLangElement MiniLang 是基于XML的“描述型语言”。所有的元素,包括节点、属性都继承自该类。它包含三个属性: lineNumber:表示解析MiniLang的源码(通常是Java)所处的行号,主要是为了便于日志记录 tagName:当前元素的tag名称,主要用于日志记录 simpleMethod:simpleMethod是一个大的“传输对象”,里面实现了MiniLang支持的所有执行方式,其作用类似于serviceengine中的serviceDispatcher。

MiniLang所有元素的父类——MiniLangElement

MiniLang 是基于XML的“描述型语言”。所有的元素,包括节点、属性都继承自该类。它包含三个属性:


  • lineNumber:表示解析MiniLang的源码(通常是Java)所处的行号,主要是为了便于日志记录
  • tagName:当前元素的tag名称,主要用于日志记录
  • simpleMethod:simpleMethod是一个大的“传输对象”,里面实现了MiniLang支持的所有执行方式,其作用类似于serviceengine中的serviceDispatcher。
该类中没有太多的功能代码,除了outputTraceMessage。它用于记录跟踪日志消息,以上提及的两个属性(lineNumber/tagName)主要用在这里。

对应于服务引擎的实现——SimpleServiceEngine

在之前一篇关于ofbizservice engine的剖析中,我们谈到了里面也有minilang相关的一个执行引擎,其实就是此处的SimpleServiceEngine。它继承了GenericAsyncEngine(这里继承的语义并不是is-a的关系,主要是代码复用,因为GenericAsyncEngine实现了runAsync,而其他的子引擎都没必要实现这个接口方法)。
SimpleServiceEngine的继承关系图:

SimpleServiceEngine实现了父类中的两个抽象run方法:


但这两个方法都不包含主要的实现逻辑,真正的逻辑被定义在私有方法:serviceInvoker中,它最终是通过SimpleMethod的静态runSimpleService方法来执行的。

BeanScript的引擎实现——SimpleMethodBsfEngine

准确来说,它是对IBM的Beanscripting 库的适配器。用于在minilang中调用Beanscript。它实现了如下方法:

其中apply以及call未提供实现(抛出异常),它在内部维护了一个上下文对象,用来存放BSFDeclaredBean,而该上下文对象用于为SimpleMethod的执行提供另一个上下文。维护上下文对象通过如下两个方法:
  • declareBean
  • undeclareBean
方法执行的主要逻辑实现位于eval中。它通过方法参数找到SimpleMethod对象,然后构造执行的上下文对象,调用SimpleMethod对象的exec执行。

MiniLang真正的执行者——SimpleMethod

SimpleMethod继承自MiniLangElement,说明它也是MiniLang中的一个元素。SimpleMethod包含了很多跟执行任务相关的代码:

当然这些方法大多是应对MiniLang可以应用场合的重载,可以看到它可以应用于简单方法、事件以及服务。最终真正的执行方法是exec方法。
当然还有一些方法是静态帮助方法。比如readOperations,它返回当前元素所有子元素所被代表的MethodOperation实例的集合,(关于MethodOperation后面会讲到,每个minilang节点都最终被影射为一个MethodOperation,由Java解释执行)。

验证检查器——MiniLangValidate

由于MiniLang是采用xml来描述任务的“语言”,因此它并不具备编程语言的很多编译检查机制。所以它采用了一些辅助方法来进行检查:包括了验证属性、验证子元素、测试元素是否为空若为空设置默认值、测试某属性是否为常量值等、是严格模式还是宽松模式以及错误处理等等

MiniLang的帮助类——MiniLangUtil

该类是MiniLang的帮助类,提供了一些方法:调用SimpleMethod的方法、类型转换/获取的方法、设置MiniLang内容的方法等

字段验证及转换器——SimpleMapProcessor

SimpleMapProcessor从上下文对象中获取到字段信息,然后进行验证以及转换(当然真正的验证以及转换逻辑并不是由他来实现的,它只是起到触发动作),然后将验证通过的字段放入目标集合中去。MiniLang会定义很多这样的MapProcessor,而SimpleMapProcessor主要用于获取这些所有的mapProcessor(内部获取,不对外公开)然后运行他们:

对于所有的mapProcessor,SimpleMapProcessor支持两种缓存,一种是基于字符串xmlResource作key的缓存,一种是基于URLxmlURL为key的缓存。而所有的runSimpleMapProcessor都是先获取到mapProcessor集合中特定的mapProcessor,然后调用其exec方法来执行验证以及转换动作(后面会有介绍)。

操作描述的基类——SimpleMapOperation

MiniLang中提供了很多的operation,而所有这些operation都继承自SimpleMapOperation这个抽象类: