用友NC语义模型红皮书-2011-07

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

用友软件股份有限公司
高级分析平台语义模型红皮书
版本:V6.0.0.20100924
目录
一、前言 (3)
1.概念 (3)
2.定位 (3)
二、结构 (3)
1.应用模型 (3)
2.语义模型 (4)
a) 定义形态 (4)
b) 执行流程 (6)
c) 数据形态 (7)
3.语义提供者 (7)
a) 接口 (7)
b) 扩展 (10)
4.函数 (14)
a) 函数解析 (14)
b) 函数扩展 (14)
5.参数 (17)
a) 参数定义 (17)
b) 参数引用 (17)
c) 参数设置 (18)
6.宏变量 (19)
7.描述器 (20)
8.数据加工 (22)
9.物化策略 (24)
10.复合语义模型 (25)
11.语义上下文 (29)
三、语义模型的管理 (32)
1.对象管理 (32)
2.环境配置 (35)
四、功能扩展 (36)
1.扩展语义提供者 (37)
2.扩展业务函数 (37)
3.使用数据加工 (37)
4.自定义执行策略 (37)
五、附录 (38)
1.入门 (38)
2.语义模型API (43)
3.语义函数 (45)
4.其他函数 (45)
5.脚本引擎 (47)
6.针对查询引擎的改进 (47)
一、前言
1.概念
SMART,即Semantic Modeling for Analysis Report Toolkit, 分析报表语义建模工具。

2.定位
二、结构
1.应用模型
上图为语义模型应用结构图。

语义模型通过语义提供者,可以将多个数据源的数据进行整合。

2.语义模型
a)定义形态
下图展示了语义模型的内部结构,
a)元数据
元数据是指描述数据的数据,是为了外界使用数据而对数据本身含义的阐述。

拿我们最常见的二维数据(行列结构)举例来说,如果只有这些行列结构的数据,对我们来说这将毫无意义。

因为我们无法知道哪一列的数据代表什么含义,无法知道如何操作这些数据,更别提由这些数据分析出有用的信息。

反过来,如果针对这些数据指定了元数据,我们就可以了解哪一列代表的业务含义,并且知道该列的数据类型、长度、精度等。

这样,我们就能对这些数据进行加工处理,分析提取出有价值的信息。

同理,语义模型的元数据是对执行语义模型后获取的二维数据的描述。

元数据针对结果数据的每一列都提供了下列信息:数据类型、字段显示名、字段名、备注、长度、精度等。

有了这些信息,我们就能知道在业务应用中该如何使用语义模型。

b)语义提供者
语义提供者,表述了一类取数方式,或者说如何提供数据的方式。

在语义模型中,语义提供者负责把一类业务取数过程以语义脚本的形式描述出来。

为了能更好的理解这个概念,我们可以打这样一个比方:NC元数据、数据仓库、报表数据、总账数据等这些可提供数据的对象好比“数据水源”,而语义提供者好比“水泵”,语义模型好比“抽水机”。

每种“数据水源”只支持特定的“水泵”
来抽取数据。

我们有了一种语义提供者“水泵”,就能抽取其对应的“数据水源”
里的数据。

语义模型中能指定多个语义提供者,就相当于“抽水机”挂接了多个“水泵”,我们就能从多个不同类型的“数据水源”来抽取数据。

语义提供者负责抽取数据,同时对外提供元数据来描述这些数据。

语义提供者的元数据一般是在语义模型内部使用。

更多细节以及语义提供者的扩展说明参见章节《语义提供者》。

c)描述器
描述器是指对数据操作的描述,例如:过滤、排序、分页、汇总等。

在语义模型中,描述器表述了对语义提供者抽取的数据的加工处理过程。

更多细节参见章节《描述器》。

d)首选项
语义模型中的首选项包括三类数据:参数、宏变量、配置项。

下面将分别介绍:
i.参数
参数是模型中代表动态信息的元素,用于响应用户的输入。

参数给用户提供了
控制模型执行过程的机会。

更多细节参见章节《参数》。

ii.宏变量
宏变量与参数类似,区别是,参数在模型执行时需要用户输入值;而宏变量不
需要与用户交互,系统后台会根据上下文计算该值。

更多细节参见章节《宏变量》。

iii.配置项
配置项用于控制语义模型的执行方式。

b)执行流程
语义模型的执行流程如下图所示:
语义提供者:
NC元数据
QDI元数据
业务数据
语义模型
...
语义函数:
nc_metadata()
smart()
report()
parameter()
macro()
...
语义模型执行过程可分为以下步骤:
第一步:语义模型脚本化
语义模型中的对象结构将转变为字符串形式的语义脚本。

第二步:脚本对象化
通过脚本引擎把语义脚本解析为脚本模型,即把字符串形式的脚本对象化。

第三步:脚本模型翻译为SQL
基于脚本模型,处理其中的语义函数,把脚本模型翻译为标准SQL语句。

运行态描述器会在这一步被处理。

第四步:执行sql,把结果集封装为DataSet,返回DataSet。

由于运行态描述器的存在,每次执行语义模型时获取的最终sql都是不同的,但是,语义模型本身对应的脚本模型是相同的。

基于性能考虑,我们可以把语义模型对应的脚本模型缓存起来。

这样一来,只有第一次执行语义模型时,我们需要完整执行上述四个步骤,接下来的每次执行,我们只需取得该缓存的脚本模型,再做第三、四步的处理即可。

c)数据形态
语义模型提供的数据可以以两种形态存在:数据集DataSet、数据表DbTable。

从数据流转的角度来说,语义模型代表了一种取数管道,数据可以从管道中抽取出来。

数据集DataSet 代表了内存中的数据,或者说,数据在内存中以数据集DataSet为载体。

数据表DbTable代表了数据库中的数据,或者说,数据在数据库中以数据表DbTable为载体。

语义模型、数据
如果把数据集中的当前数据持久化到数据库中,数据就以数据表的形式存在;把数据从数据库中加载到内存中,就完成了数据表到数据集的转换;数据表可以以语义提供者的形式构成语义模型,完成数据从数据表到语义模型的流转;并且,语义模型经由视图化执行,最终的结果集将以数据表的形式呈现。

数据在不同形态间流转时,改变的是数据载体,不变的数据本身的结构,即元数据。

3.语义提供者
语义提供者,表述了一类取数方式,或者说如何提供数据的方式。

在语义模型中,语义提供者负责把一类业务取数过程以语义脚本的形式描述出来。

a)接口
语义提供者包括NC元数据、DW元数据、以及语义脚本和业务代码扩展提供者。

提供总帐、HR、供应链、报表等业务数据扩展。

其整个体系结构可由下图表示:
SQL 的应以提供二维
其中,Provider 是语义提供者的接口;
SemanticProvider 是基础扩展抽象类,对能把取数过程以脚本形式描述的语义提供者可继承此类;
SemanticDataProvider 是语义数据扩展抽象类,对不能以脚本形式描述取数过程,只能提供二维数据的提供者,可继承此类。

SemanticSqlProvider 适用于提供者在运行时根据执行环境context 返回不同取数sql 与SqlProvider 的区别在于:
SqlProvider 的sql 结构在定义态已经确定;
SemanticSqlProvider 是在运行时,经过一系列业务处理,返回最终取数sql.
上述图中,蓝色代表具体实现类。

通过以上的介绍我们可以得知,Provider 定义了语义提供者的接口规范,SemanticProvider 、SemanticDataProvider 、SemanticSqlProvider 则是我们具体实现提供者时要继承的抽象类。

现对这四个类的主要接口做重点介绍。

Provider
●SemanticProvider
●SemanticDataProvider
SemanticSqlProvider
b)扩展
前面介绍了语义提供者的整个体系结构,现在我们拿一个具体例子来讲解如何实现一个语义提供者。

我们以比较简单的“数据表”这类取数方式来做示例。

扩展语义提供者可分为以下三步:
i.实现语义提供者类
由前文介绍,我们知道实现一个提供者有三种方式:
1.继承SemanticProvider:能把取数过程以脚本形式描述的语义提供者可继
承此类
我们现以数据表提供者为例来讲解如何以此种方式实现语义提供者。

数据表提供者对应的实现类为:DbTableProvider,该类继承于
SemanticProvider,实现了接口provideMetaData(SmartContext context) ,
provideScript(SmartContext context)。

数据表提供者,是把NC元数据底层数据模型中的一张表作为操作对象,从中抽取数据。

其在语义模型中的操作是这样的:
在上级“模块”目录上选中模块“平台”,展开后在子节点上选中“sm_user”
这张表。

在数据表提供者DbTableProvider中,我们只需要存储一条信息:表名。

这些信息可以看做取数过程的业务描述,接下来我们做的就是把这些业务描述
转换为以语义模型中的概念来进行描述。

实现provideMetaData(SmartContext context)接口:有了表名信息,我们就可
以把其列信息拿到,列Column解析为字段Field,每列对应一个字段,多个
列对应的多个字段就组合为元数据MetaData。

实现provideScript(SmartContext context)接口:数据表提供者比较简单,直
接返回表名即可。

到此,我们的数据表语义提供者类就实现完毕。

2.继承SemanticDataProvider:不能以脚本形式描述取数过程,只能提供二
维数据的提供者,可继承此类
例如,供应链中有些查询并不能直接通过一条sql就能查出,中间可能经
过一系列复杂的代码运算逻辑来构造这个结果数据,这时我们就可以继承
SemanticDataProvider来实现语义提供者。

继承此类只需要实现provideData(SmartContext context)接口:在该方法
中,我们编写运算逻辑,构造最终的结果数据DataSet,返回之即可。

在此我们有必要介绍下DataSet的结构。

DataSet主要包含两部分:元数
据MetaData,数据容器Object[][](即二维数组)。

Object[][]即是
最终的结果数据,MetaData是对数据的描述信息,包含对应字段信息:字
段名、数据类型、数据精度等。

3.继承SemanticSqlProvider:应用方式与SemanticDataProvider类似,不同在于,
SemanticDataProvider最终返回二维数据,而SemanticSqlProvider返回sql语句。

ii.实现语义提供者设计向导类
有了语义提供者类,我们还需要一个设计器来设计语义提供者。

每个设计器都
需要实现接口IProviderDesignWizard。

该接口只有一个方法:
/**
*@param parent父窗口。

为ProviderStepPanel,藉
此可获得SmartModelWizardShareObject(向导模型,包含向导
共享数据)
*@param provider待修改的语义提供者
*@param context上下文
*@return设计完成后的语义提供者
*/
public Provider design(Container parent,
Provider provider, SmartContext context);
当设计语义提供者时,会调用此方法,调用完成返回提供者实例。

数据表提供者设计向导类为DbTableProviderDesigner。

其界面效果如下图所示:
其具体处理流程为:调用design()方法,打开一如上图所示对话框,用户选中表后,点“确定”按钮,构造一个DbTableProvider实例,返回之。

iii.配置文件注册
编写完语义提供者类、设计向导类,我们还需在配置文件中注册该种语义提供者,以便在语义模型能加载到。

所谓注册,即在配置文件中增加相应配置项。

为方便各模块扩展语义提供者,在开发环境下,配置文件存放位置为各模块resources下的smart目录:
${NC_Project}/resources/smart/smart_${模块号}.xml
如总帐项目扩展配置文件路径为:
gl/resources/smart/smart_gl.xml
这样在安装盘中,各模块扩的扩展配置文件将都在NC_HOME/resources/smart/目录中。

具体配置信息如下:
每个语义提供者注册项包含五种属性:名称、图标路径、类型、语义提供者类名、设计向导类名。

其格式为:
其中,type类型是用于区分预置的语义提供者和用户自定义的语义提供者,其有效值有:preset、custom。

分别对应系统预置、用户自定义两种类别。

一般用户在自己扩展实现自定义的语义提供者时,可以直接去掉type项,或者把该项设置为custom。

以数据表提供者举例,其配置项为:
至此,我们的语义提供者就全部实现了,在语义模型的设计向导中就会支持该类型的语义提供者。

4.函数
a)函数解析
语义脚本支持sql语法和自定义函数的混合编写。

系统默认函数有smart(), nc_metadata(), qdi_metadata(), parameter(),macro(),后续会扩展字符串函数、时间函数等。

NC公式统一走宏变量定义。

b)函数扩展
语义模型支持对其函数进行扩展,用户可以根绝业务需求添加自定义函数。

具体步骤如下:
1、根据函数接口(ISemanticCommand)实现自定义函数。

类图示意如下:
接口中API如下:
2、在函数扩展配置文件进行配置。

默认配置文件路径为${NC_Home}/resources/smart/function_default.xml。

为方便各模块扩展函数,在开发环境下,配置文件存放位置为各模块resources下的smart目录:
${NC_Project}/resources/smart/function_${模块号}.xml
如总帐项目扩展配置文件路径为:
gl/resources/smart/function_gl.xml
这样在安装盘中,各模块的扩展配置文件将都在NC_HOME/resources/smart/目录中。

配置文件示例如下:
配置文件中是根据驱动名称进行组织的,驱动总共分为两类SmartFunctionDriver和DBFunctionDriver。

之所以对驱动进行区分是因为在不同的功能点,加载的函数驱动可能不同。

在实际配置过程中,用户可以根据自己的需要把自定义的函数类全路径名放在已有的驱动定义或新增加自定的驱动定义中,即可完成函数的扩展。

5.参数
参数是模型中代表动态信息的元素,用于响应用户的输入。

在模型的执行过程中,可以根据参数值的不同来影响结果数据。

参数常用于对筛选条件的设置上。

示意图如下:
a)参数定义
参数是与具体的模型绑定的,在每个模型的设计过程中都可以对参数进行定义。

参数的类型分为:字符,数值,枚举和参照。

当类型为枚举时,枚举项为用“@”分隔的枚举值,或者是一个单字段的查询SQL;当类型为参照时,枚举项为基础参照名,或者是用尖括号括起的自定义参照的类名。

在定义的时候需要注意,参数的编码要保证互不相同。

b)参数引用
参数引用主要在模型设计中的筛选描述器部分,在筛选描述器的条目中,值类型选择为参数时候,则会在值字段的下拉列表中列出相应的参数。

另外在模型设计的“Smart脚本”中,我们提供了“parameter”函数,在函数列表中双击,则会弹出参数选择框。

c)参数设置
运行态要求用户首先对参数进行设置,当报表引用了多个语义模型时,参数将通过多页签设置,每个页签代表一个模型。

另外需要注意的是,模型在运行态时会对参数是否被引用进行检查,最终的设置界面上只会显示被引用的参数。

d)参照依赖
➢设计态增加“参照依赖”列,参照型的参数可以使用参照依赖,其他类型即使设置也不会起作用
➢“参照依赖”中支持parameter,macro 函数;例如:
sm_user.cuid=parameter('param1') and pk_org=macro('m1')
➢如果参照是树表形式的,并且需要分别对树和表进行设置,则输入框中输入的条件用“;”
分割。

➢定义态的默认值设置支持参照依赖,即参照显示的值会根据依赖的条件过滤。

具体设置:
e)自定义参照
参照类型参数支持对参照编辑的自定义设置。

实现方法:在设计态,属性列编辑框中通过注册自定义编辑器的方式实现,方式为“<类路径>”。

相关的具体规则如下:
➢编辑界面基类:nc.ui.pub.smart.designer.preference.CustomParamDlg ,自定义编辑器必须/**
* 利用参数信息构建UI
* @param info 参数信息
* @throws Exception
*/
public abstract void buildUI(CustomParamInfo info) throws Exception;
/**
* 获取参数编辑的返回值
* @return
* @throws Exception
*/
public abstract String getParamValue() throws Exception;
其中buildUI方法传递的参数CustomParamInfo相关说明:
/**
* 参照当前值
*/
private String currentValue;
/**
* 当前数据源
*/
private String dsName;
/**
* 当前参数的哈希表
*/
private HashMap<String, Parameter> paramMap;
3、使用说明:见下图
6.宏变量
宏变量引申自程序设计中的宏,其表达式会被替换为字符串,并在最终的查询语句中可以被完全替换。

宏变量根据作用域分为全局宏变量和模型宏变量。

故名思意,全局宏变量用于全局共享,在任何语义模型中都可以直接引用。

模型宏变量与具体的语义模型相关,其只在当前模型中其作用。

全局宏变量中包含多个预置宏变量,如LoginDate,LoginUser等,方便共享。

宏变量其定义与参数类似,不同之处在于其类型有两种选择“公式”和“SQL语句”。

公式只是其表达式支持NC公式的编辑;SQL语句是指一般的SQL语句,但默认情况下取值只能取第一行第一列的值。

宏变量示意图如下:
宏变量的引用与参数相同,分别在筛选描述器和Smart脚本的公式(macro)中可以对其引用。

另外与参数区别的是,由于宏变量都是固定的值,因此不需要与用户进行交互,所有在浏览态没有相应的设置界面。

7.描述器
Descriptor是指对数据操作的描述,例如:过滤、排序、分页、汇总等。

现支持以下几种描述器:
名称对应类用途结构对应界面设计

汇总描述器AggrDescriptor 对数据做汇总
处理,相当于
sql中的group
by 包含汇总条件、汇总字段
两部分

数据唯一描述符DistinctDescriptor 清除数据中的
重复行,相当
于sql中的
distinct
不持有属性,
以其存在与否
来判断是否做
distinct处理

过滤描述器FilterDescriptor 对数据做过滤
处理,相当于
sql中的where 包含树形结构
的过滤条件
FilterDescPanel
表连接描述器JoinDescriptor 表示表之间的
连接关系,相
包含连接条件JoinStepPanel
描述器可在设计态、运行态两处使用。

在设计语义模型时,我们通过设计向导能构造设计态的描述器,保存于语义模型中;
在执行语义模型时,我们可以另外自己构造运行态的描述器,对语义模型进行再处理。

对于语义模型的使用者,一般接触到的是运行态的描述器,现对这部分进行详细讲解。

构造描述器:对于提供了设计界面的描述器,可以调用界面类来构造描述器;也可以在后台直接构造描述器。

调用provide接口:把上述描述器封装到描述器数组Descriptor[] descs,然后传入语义模型相应的provide接口方法中:
上述方法中的Descriptor[] descs 即是运行态描述器,藉此提供了对语义模型进行再处理的可能。

8.数据加工
a)概念
数据加工是语义模型提供的一类取数方式,支持用户使用java代码来定义一段取数逻辑。

b)定位
考虑到在现实应用中业务逻辑的复杂性,单纯依赖sql语句,用户并不是总能得到想要的结果集。

因此提供了在语义模型嵌入Java代码的功能,用于单纯sql处理不了的场景。

由于数据加工是在从数据库中取出结果集后在内存中进行操作,考虑到资源和效率问题,我们建议只有在SQL解决不了的数据处理要求,才使用数据加工实现。

由于在数据加工中提供的通过Java代码实现相关数据处理的功能,理论上讲其可以满足任意相关的业务逻辑需求,复杂的业务逻辑算法需要在实际应用开发中按照不同情况和场景灵活使用。

c)执行原理
在使用时,数据加工分为两个步骤:
第一步使用java代码定义取数逻辑,最终返回sql语句或结果集DataSet。

基于性能考虑,推荐返回值为sql;
第二步定义元数据,即对上述代码返回的数据的描述,包括:有哪几列、每一列的数据类型、长度、精度等;
执行时,上述定义的java代码会在后台被调用,拿到返回的sql语句或结果集DataSet (DataSet需要持久化到数据库中的临时表中),然后和其他逻辑表(provider)进行复合取数。

d)使用
使用方式如下:
弹出设计界面如下:
在上述编辑器中编辑java代码,左边提供了辅助代码片段生成向导。

步骤“元数据”,是要求代码设计者对代码执行完后的结果数据进行描述,即返回几列数据,每列的列名、数据类型等信息。

(该步骤的改进方案为:元数据自动生成,通过预执行一遍代码来实现。

不过手工设置避免不了,因为大部分代码在设计态很难成功执行)
e)常见问题
a.数据加工java代码中,调用语义模型的类时,直接使用类名,而对业务部门的类,
需要使用全路径名。

b.java代码中封装DataSet时,需要设置元数据MetaData(具体参见相关类)。

c.java代码中通过调用代码setDataSet(DataSet)设置最终需要返回的结果数据集
DataSet,通过调用代码setResultSQL(sql)设置sql返回值。

d.这部分代码是在后台调用,切忌调用UI类
e.java代码最终生成的类继承于nc.pub.smart.model.code.CodeProcessor ,实现其
process() 方法
f.java代码生成的类放在NC_Home\modules\ufob\META-INF\var\classes 下
9.物化策略
我们可以对一个语义模型设置定时策略,定时把语义模型执行后的数据持久化到指定数据源上指定的数据表中。

通过提供这种功能,我们就能把一些执行效率较低的语义模型预先调度执行,到真正取数时,直接从物化表中取数,减少执行等待过程。

物化策略使用有其局限性,只有在只使用语义模型本身的字段时,才会从物化表直接取数;如果需要取语义模型本身未定义的字段(例如语义字段等),则会把语义模型从头执行一遍,不再使用物化表。

10.复合语义模型
复合语义模型,指的是,我们在定义语义模型时,可以引用已经存在的语义模型。

对这种引用了其他语义模型的语义模型,我们称之为复合语义模型。

下图形象的阐释了复合语义模型的嵌套结构。

应用复合语义模型能够达到数据集成的效果。

在上图中,我们注意到,每个语义模型均可以定义自己的执行数据源,也就是说,复合语义模型引用的原子语义模型的执行数据源可以互不相同,从而,我们就能支持多数据源取数功能。

数据从不同数据源抽取出来,然后以语义模型这种统一的形式对外提供数据,这样就达到了数据集成的效果。

创建复合语义模型有两种方式:设计向导、语义脚本。

下面我们将针对这两种方式做
分别介绍。

●设计向导方式
在语义模型设计向导中,选择“选择表”步骤,
单击右边的“语义模型”按钮,弹出语义模型参照对话框,
选中语义模型,单击“确定”按钮。

这样就可以把选中的语义模型引用到当前设计的语义模型中。

这时,原子语义模型是以语义提供者的形式存在于复合语义模型中。

●语义脚本方式
我们可以在语义脚本中通过使用语义函数smart()来引用语义模型(smart() 的语法规则
参见附录)。

在语义模型设计向导中,选择“选择表”步骤,
在右边单击“语义脚本”按钮,弹出“语义脚本编辑器”对话框,
这时,我们可以以语义脚本的形式来创建语义模型。

在“语义函数”页签选中“smart”函数,双击,弹出语义模型参照对话框,
选中语义模型,单击“确定”按钮。

这时,在脚本编辑框中会自动添加一段脚本“smart(‘user’)”,
当然,如果我们事先知道被引用的语义模型的编码,我们也可以在文本框中直接编辑脚本。

11.语义上下文
语义上下文SmartContext提供了语义模型运行时环境,包括了如下有用信息:例如参数值、宏变量值、当前模型、执行数据源等。

相关方法列表如下:
方法名称参数功能
SmartModel getBuildingSmartModel()获得当前正在build的模型。

对复合模型,不一定是当前正在执行的模型
String getDsName4Exec()获取执行数据源
Object getMacroValue(String macro)macro:宏变量
编码
获得宏变量的值
Object
getParameterValue(String paramCode)paramCode:参
数编码
获得参数的值
12.脚本规则
脚本规则是指针对语义脚本的处理逻辑,具体处理过程如下图所示:
脚本规则支持扩展,业务部门可以通过扩展规则、直接操作内存脚本模型,藉此实现特定功能,例如:复杂权限控制等。

规则的扩展机制如下:
1)实现规则类
规则的统一接口为:nc.pub.smart.script.engine.rule.IScriptRule
主要接口方法为:
/**
* 执行规则
*/
public Select exec() throws Exception;
在该接口中,我们可以操作传过来的脚本模型Select各部分,包括select字段列表、from、where、orderBy、groupBy等。

修改完脚本模型,把其返回即可。

我们可以继承AbsScriptRule来实现自定义的规则。

2)配置文件注册
编写完规则实现类,我们还需在配置文件中注册该规则,以便在语义模型能加
载到。

所谓注册,即在配置文件中增加相应配置项。

为方便各模块扩展规则,在开发环境下,配置文件存放位置为各模块resources
下的smart目录:
${NC_Project}/resources/smart/smart_rule_${模块号}.xml
如总帐项目扩展配置文件路径为:
gl/resources/smart/smart_rule_gl.xml
这样在安装盘中,各模块扩的扩展配置文件将都在NC_HOME/resources/smart/
目录中。

具体配置信息如下:
每个规则注册项包含三种属性:显示名、规则class全路径名、优先级。

其格
式为:。

相关文档
最新文档