> For the complete documentation index, see [llms.txt](https://potoyang.gitbook.io/spring-in-action-v4/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://potoyang.gitbook.io/spring-in-action-v4/untitled-2/untitled-3/untitled.md).

# 8.2.3　流程数据

如果你曾经玩过那种老式的基于文字的冒险游戏的话，那么当从一个地方转移到另一个地方时，你会偶尔发现散布在周围的一些东西，你可以把它们捡起来并带上。有时候，你会马上需要一件东西。其他的时候，你会在整个游戏过程中带着这些东西而不知道它们是做什么用的 —— 直到你到达游戏结束的时候才会发现它是真正有用的。

在很多方面，流程与这些冒险游戏是很类似的。当流程从一个状态进行到另一个状态时，它会带走一些数据。有时候，这些数据只需要很短的时间（可能只要展现页面给用户）。有时候，这些数据会在整个流程中传递并在流程结束的时候使用。

**声明变量**

流程数据保存在变量中，而变量可以在流程的各个地方进行引用。它能够以多种方式创建。在流程中创建变量的最简单形式是使用 `<var>` 元素：

```markup
<var name="customer" class="com.springinaction.pizza.domain.Customer" />
```

这里，创建了一个新的 Customer 实例并将其放在名为 customer 的变量中。这个变量可以在流程的任意状态进行访问。

作为行为状态的一部分或者作为视图状态的入口，你有可能会使用 `<evaluate>` 元素来创建变量。例如：

```markup
<evaluate result="viewScope.topppingsList" expression="T(com.springinaction.pizza.domain.Topping).asList()" />
```

在本例中，`<evaluate>` 元素计算了一个表达式（SpEL 表达式）并将结果放到了名为 toppingsList 的变量中，这个变量是视图作用域的（我们将会在稍后介绍关于作用域的更多概念）。

类似地，`<set>` 元素也可以设置变量的值：

```markup
<set name="flowScope.pizza" value="new com.springinaction.pizza.domain.Pizza()" />
```

`<set>` 元素与 `<evaluate>` 元素很类似，都是将变量设置为表达式计算的结果。这里，我们设置了一个流程作用域内的 pizza 变量，它的值是 Pizza 对象的新实例。

当我们在 8.3 小节开始构建真实工作的 Web 流程时，你会看到这些元素是如何具体应用在实际流程中的。但首先，让我们看一下变量的流程作用域、视图作用域以及其他的一些作用域是什么意思。

**定义流程数据的作用域**

流程中携带的数据会拥有不同的生命作用域和可见性，这取决于保存数据的变量本身的作用域。Spring Web Flow 定义了五种不同作用域，如表 8.2 所示。

| 范围           | 生命作用域和可见性                                      |
| ------------ | ---------------------------------------------- |
| Conversation | 最高层级的流程开始时创建，在最高层级的流程结束时销毁。被最高层级的流程和其所有的子流程所共享 |
| Flow         | 当流程开始时创建，在流程结束时销毁。只有在创建它的流程中是可见的               |
| Request      | 当一个请求进入流程时创建，在流程返回时销毁                          |
| Flash        | 当流程开始时创建，在流程结束时销毁。在视图状态渲染后，它也会被清除              |
| View         | 当进入视图状态时创建，当这个状态退出时销毁。只在视图状态内是可见的              |

当使用 `<var>` 元素声明变量时，变量始终是流程作用域的，也就是在定义变量的流程内有效。当使用 `<set>` 或 `<evaluate>` 的时候，作用域通过 name 或 result 属性的前缀指定。例如，将一个值赋给流程作用域的 theAnswer 变量：

```markup
<set name="flowScope.theAnswer" value="42" />
```

到目前为止，我们已经看到了 Web 流程的所有原材料。是时候将其组装起来形成一个成熟且完整功能的 Web 流程了。当我们这样做的时候，请睁大你的眼睛观察，比如我是如何将数据存储在各作用域的变量中的。
