Spring Web Flow — наследование потоков (flow Inheritance)
9. Spring Web Flow — наследование потоков (flow inheritance)
9.1. Введение
Наследование потоков позволяет внедрить конфигурацию одного потока в другой поток. Наследование может происходить как на уровне потока, так и состояния. Общий случай использования наследования для родительского потока является определение глобальных переходов и обработчиков исключений, настройки которых могут быть унаследованы каждым из подпотоков.
Чтобы можно было найти родительский поток, он должен быть добавлен в flow-registry как и любой другой поток.
9.2. Является ли наследование потоков таким же как и наследование в Java?
Наследование потоков похоже на наследование в Java в том смысле, что определенные элементы из родительского потока доступны в подпотоке, однако есть ключевые различия.
Подпоток не может переопределить элементы родительского потока. Одинаковые элементы между подпотоком и родительским потоком будут объединены. Уникальные элементы родительского потока будут добавлены в подпоток.
Подпоток может унаследовать несколько родительских потоков. Наследование в Java возможно только от одного класса.
9.3. Типы наследования потоков
9.3.1. Наследование на уровне потока
Наследование на уровне потока определяется атрибутом parent элемента flow. Атрибут содержит разделенный запятыми список идентификаторов, от которых происходит наследование. Подпоток будет наследовать элементы и контент каждого родителя в порядке, указанном в списке, в результирующий поток. Результирующий поток первого слияния будет добавлен в подпоток во втором слиянии и так далее.
1 |
<flow parent="common-transitions, common-states"> |
9.3.2. Наследование на уровне состояния
Наследование на уровне состояния похоже на наследование на уровне потока с тем исключением, что только одно состояние наследуется от родителя, а не от всего потока.
В отличии от наследования потока, разрешен только один родитель. Кроме того, идентификатор состояния потока, от которого наследуются, так же должен быть определен. Идентификаторы для потока и состояния внутри этого потока разделяются #.
Родительское и внутреннее состояние должно быть одного типа. Экземпляр view-state не может быть унаследован от end-state, только от другого view-state.
1 |
<view-state id="child-state" parent="parent-flow#parent-view-state"> |
9.4. Абстрактные потоки
Часто родительские потоки проектируются не для прямого выполнения. Для того, чтобы защитить такие потоки от запуска они маркируются как абстрактные. Если попытаться запустить абстрактный поток, то будет выброшено исключение FlowBuilderException.
1 |
<flow abstract="true"> |
9.5. Алгоритм наследования
При наследовании подпотока от его родителя, по существу, происходит то, что родитель и подпоток сливаются вместе и создается новый поток. Для каждого элемента из языка Web Flow существуют правила, которые регулируют, как конкретный элемент будет объединяться.
Есть два типа элементов: объединяемые и необъединяемые. Объединяемые элементы всегда будут пытаться объединиться, если они имеют одинаковый тип. Необъединяемые элементы в потоке родителя или подпотоке всегда будут содержаться в результирующем потоке нетронутыми. Они не будут изменены в результате процесса объединения.
Важно.
Пути к внешним ресурсам родительского потока должны быть абсолютными. Относительные пути будут повреждены при слиянии потоков, кроме случаев когда они находятся в одной директории. После объединения все относительные пути родительского потока станут относительными к подпотоку.
9.5.1. Объединяемые элементы
Если элементы имеют одинаковый тип и их ключи атрибутов идентичны, то контент из родительского потока будет объединен с элементом подпотока. Алгоритм объединения будет объединять каждый саб-элемент родительского и внутреннего потока. В противном случае родительский элемент будет добавлен в подпоток как новый элемент.
В большинстве случаев, элементы, добавленные из родительского потока, будут добавлены после элементов подпотока. Исключение из этого правила — элементы действия (evaluate, render и set), которые будут добавлены в начале. Это позволит результатам родительских действий быть использованными в действиях подпотока.
Объединяемые элементы:
- action-state: id
- attribute: name
- decision-state: id
- end-state: id
- flow: always merges
- if: test
- on-end: always merges
- on-entry: always merges
- on-exit: always merges
- on-render: always merges
- on-start: always merges
- input: name
- output: name
- secured: attributes
- subflow-state: id
- transition: on and on-exception
- view-state: id
9.5.2. Необъединяемые элементы
Необъединяемые элементы:
- bean-import
- evaluate
- exception-handler
- persistence-context
- render
- set
- var
2