# 9. 流继承
# 9.1.导言
流继承允许一个流继承另一个流的配置。继承可以在流和状态两个级别上发生。一个常见的用例是父流定义全局转换和异常处理程序,然后每个子流都可以继承这些设置。
为了找到父流,必须像其他任何流一样将其添加到flow-registry
中。
# 9.2.流继承和 Java 继承一样吗?
流继承类似于 Java 继承,因为在父级中定义的元素是通过子级公开的,但是,有一些关键的区别。
子流不能覆盖父流中的元素。父流和子流之间的类似元素将被合并。父流中的唯一元素将被添加到子流中。
子流可以从多个父流继承。Java 继承仅限于一个类。
# 9.3.流继承的类型
# 9.3.1.流级继承
流级继承由flow
元素上的parent
属性定义。属性包含一个用逗号分隔的流标识符的列表。子流将按列出的顺序从每个父流继承,将元素和内容添加到结果流中。来自第一次合并的结果流将被认为是第二次合并中的子流,依此类推。
<flow parent="common-transitions, common-states">
# 9.3.2.状态级继承
状态级继承类似于流级继承,只是从父级继承了一个状态,而不是整个流。
与流继承不同,只允许有一个父代。此外,还必须定义要继承的流状态的标识符。流的标识符和该流中的状态由一个 # 分隔。
父状态和子状态必须是同一类型的。例如,一个视图状态不能从一个结束状态继承,只能从另一个视图状态继承。
<view-state id="child-state" parent="parent-flow#parent-view-state">
[[note](images/note.png) | Note |
---|---|
流级继承的意图是将公共状态定义为 添加到多个流定义中并在多个流定义之间共享,而状态级继承的意图 是从单个 父状态扩展并合并。流级继承非常适合组合 和多重继承,但是在状态级,你仍然只能从单个父状态继承 。 |
# 9.4.抽象流
通常,父流的设计不是为了直接执行。为了保护这些流不被运行,它们可以标记为abstract
。如果一个抽象流试图运行,将抛出一个FlowBuilderException
。
<flow abstract="true">
# 9.5.继承算法
当一个子流继承自它的父流时,本质上发生的情况是父流和子流合并在一起以创建一个新的流。对于 Web 流定义语言中的每个元素都有规则,这些规则控制该特定元素如何合并。
有两种类型的元素:可合并和不可合并。如果元素相似,可合并元素将始终尝试合并在一起。父流或子流中的不可合并元素将始终完整地包含在结果流中。它们不会作为合并过程的一部分进行修改。
[[note](images/note.png) | Note |
---|---|
到父流中的外部资源的路径应该是绝对的。 当两个流合并时,相对路径将中断,除非父流和子流位于同一目录中。 一旦合并,父流中的所有相对路径将变得相对于子流。 |
# 9.5.1.可合并元素
如果元素的类型相同,且其键控属性相同,则父元素的内容将与子元素合并。合并算法将继续合并合并父元素和子元素的每个子元素。否则,父元素将作为一个新元素添加到子元素中。
在大多数情况下,添加的父流中的元素将在子流中的元素之后添加。此规则的例外包括将在开始时添加的动作元素(评估、渲染 和 集)。这允许子操作使用父操作的结果。
可合并的要素是:
动作状态:ID
属性:Name
决策状态:ID
结束状态:ID
流程:总是合并
如果:测试
端:总是合并
入门:总是合并
On-Exit:总是合并
On-Render:总是合并
启动:总是合并
输入:Name
输出:Name
安全:属性
子流-状态:id
转换:ON 和 ON-Exception
视图-状态:id
# 9.5.2.不可合并元素
不可合并的要素是:
Bean-进口
evaluate
异常处理程序
持久性-上下文
render
set
VAR