system-setup.md 13.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
# 10. 系统设置

## 10.1.导言

本章将向你展示如何设置在任何 Web 环境中使用的 Web 流系统。

## 10.2.Java 配置和 XML 命名空间

Web 流为基于 Java 和 XML 的配置提供了专门的配置支持。

要开始使用基于 XML 的配置,请声明 WebFlow Config XML 名称空间:

```
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:webflow="http://www.springframework.org/schema/webflow-config"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/webflow-config
           http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd">

    <!-- Setup Web Flow here -->

</beans>
		
```

要在`@Configuration`类中开始使用 Java 配置扩展`AbstractFlowConfiguration`:

```
import org.springframework.context.annotation.Configuration;
import org.springframework.webflow.config.AbstractFlowConfiguration;

@Configuration
public class WebFlowConfig extends AbstractFlowConfiguration {

}
		
```

## 10.3.基本系统配置

下一节将展示在应用程序中设置 Web 流系统所需的最小配置。

### 10.3.1.FlowRegistry

`FlowRegistry`的 XML 中注册你的流:

```
<webflow:flow-registry id="flowRegistry">
    <webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
</webflow:flow-registry>
			
```

在 Java 中的`FlowRegistry`中注册你的流:

```
@Bean
public FlowDefinitionRegistry flowRegistry() {
    return getFlowDefinitionRegistryBuilder()
        .addFlowLocation("/WEB-INF/flows/booking/booking.xml")
        .build();
}
			
```

### 10.3.2.流动执行器

部署 FlowExecutor,这是用于执行 XML 流的中心服务:

```
<webflow:flow-executor id="flowExecutor" />
			
```

部署 FlowExecutor,这是用于在 Java 中执行流的中心服务:

```
@Bean
public FlowExecutor flowExecutor() {
    return getFlowExecutorBuilder(flowRegistry()).build();
}
			
```

请参阅本指南的 Spring MVC 和 Spring Faces 部分,分别介绍如何将 Web 流系统与 MVC 和 JSF 环境集成。

## 10.4.flow-registry 选项

本节将探讨流注册中心配置选项。

### 10.4.1.指定流位置

使用`location`元素指定要注册的流定义的路径。默认情况下,流被分配的注册表标识符等于其文件名减去文件扩展名,除非定义了注册表池路径。

在 XML 中:

```
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
			
```

在 Java 中:

```
return getFlowDefinitionRegistryBuilder()
        .addFlowLocation("/WEB-INF/flows/booking/booking.xml")
        .build();
			
```

### 10.4.2.分配自定义流标识符

指定一个 ID,以便将自定义注册表标识符分配给 XML 中的流:

```
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" id="bookHotel" />
			
```

指定一个 ID,以便将自定义注册表标识符分配给 Java 中的流:

```
return getFlowDefinitionRegistryBuilder()
        .addFlowLocation("/WEB-INF/flows/booking/booking.xml", "bookHotel")
        .build();
			
```

### 10.4.3.分配流元属性

使用`flow-definition-attributes`元素将自定义的元属性分配给已注册的流。

在 XML 中:

```
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml">
    <webflow:flow-definition-attributes>
        <webflow:attribute name="caption" value="Books a hotel" />
    </webflow:flow-definition-attributes>
</webflow:flow-location>
			
```

在 Java 中:

```
Map<String, Object> attrs = ... ;

return getFlowDefinitionRegistryBuilder()
        .addFlowLocation("/WEB-INF/flows/booking/booking.xml", null, attrs)
        .build();
			
```

### 10.4.4.使用位置模式注册流

使用`flow-location-patterns`元素来注册与特定资源位置模式匹配的流:

在 XML 中:

```
<webflow:flow-location-pattern value="/WEB-INF/flows/**/*-flow.xml" />
			
```

在 Java 中:

```
return getFlowDefinitionRegistryBuilder()
        .addFlowLocationPattern("/WEB-INF/flows/**/*-flow.xml")
        .build();
			
```

### 10.4.5.流量定位基准路径

使用`base-path`属性为应用程序中的所有流定义一个基本位置。然后,所有的流动位置都相对于基本路径。基本路径可以是资源路径,例如“/WEB-INF”,或者是 Classpath 上的位置,例如“ Classpath:org/springframework/webflow/samples”。

在 XML 中:

```
<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF">
    <webflow:flow-location path="/hotels/booking/booking.xml" />
</webflow:flow-registry>
			
```

在 Java 中:

```
return getFlowDefinitionRegistryBuilder()
        .setBasePath("/WEB-INF")
        .addFlowLocationPattern("/hotels/booking/booking.xml")
        .build();
			
```

定义了基本路径后,分配流标识符的算法会略有变化。流现在将被分配的注册表标识符等于它们的基本路径和文件名之间的路径段。例如,如果流定义位于“/WEB-INF/hotels/booking/booking-flow.xml”,而基本路径是“/WEB-INF”,则该流的剩余路径是“Hotels/booking”,它将成为流 ID。

|[[提示](images/tip.png)|Directory per flow definition|
|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------|
|回想一下,将每个流定义打包在一个唯一的目录中是一种最佳实践。<br/>这提高了模块化,允许使用流定义打包依赖的资源。<br/>它还防止了两个流在使用约定时具有相同的标识符。|                             |

如果没有指定基路径,或者流定义直接位于基路径上,则使用文件名(减去扩展名)中的流 ID 分配。例如,如果流定义文件是’booking.xml’,那么流标识符只是’booking’。

与注册表基路径相结合时,位置模式的功能特别强大。而不是流标识符成为“\*-流”,它们将基于目录路径。例如,在 XML 中:

```
<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF">
    <webflow:flow-location-pattern value="/**/*-flow.xml" />
</webflow:flow-registry>
			
```

在 Java 中:

```
return getFlowDefinitionRegistryBuilder()
        .setBasePath("/WEB-INF")
        .addFlowLocationPattern("/**/*-flow.xml")
        .build();
			
```

在上面的示例中,假设在`/user/login``/user/registration``/hotels/booking``/flights/booking`目录中有位于`WEB-INF`中的流 ID,则最终得到的流 ID 分别为`user/login``hotels/booking``flights/booking`

### 10.4.6.配置 FlowRegistry 层次结构

使用`parent`属性在层次结构中将两个流注册中心链接在一起。当查询子注册中心时,如果它找不到请求的流,它将委托给其父注册中心。

在 XML 中:

```
<!-- my-system-config.xml -->
<webflow:flow-registry id="flowRegistry" parent="sharedFlowRegistry">
    <webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
</webflow:flow-registry>

<!-- shared-config.xml -->
<webflow:flow-registry id="sharedFlowRegistry">
    <!-- Global flows shared by several applications -->
</webflow:flow-registry>
			
```

在 Java 中:

```
@Configuration
public class WebFlowConfig extends AbstractFlowConfiguration {

    @Autowired
    private SharedConfig sharedConfig;

    @Bean
    public FlowDefinitionRegistry flowRegistry() {
        return getFlowDefinitionRegistryBuilder()
                .setParent(this.sharedConfig.sharedFlowRegistry())
                .addFlowLocation("/WEB-INF/flows/booking/booking.xml")
                .build();
    }
}

@Configuration
public class SharedConfig extends AbstractFlowConfiguration {

    @Bean
    public FlowDefinitionRegistry sharedFlowRegistry() {
        return getFlowDefinitionRegistryBuilder()
                .addFlowLocation("/WEB-INF/flows/shared.xml")
                .build();
    }
}
			
```

### 10.4.7.配置自定义 FlowBuilder 服务

使用`flow-builder-services`属性定制用于在流注册中心中构建流的服务和设置。如果没有指定 flow-builder-services 标记,则使用默认的服务实现。定义标记时,只需引用要自定义的服务。

在 XML 中:

```
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
    <webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
</webflow:flow-registry>

<webflow:flow-builder-services id="flowBuilderServices" />
			
```

在 Java 中:

```
@Bean
public FlowDefinitionRegistry flowRegistry() {
	return getFlowDefinitionRegistryBuilder(flowBuilderServices())
            .addFlowLocation("/WEB-INF/flows/booking/booking.xml")
            .build();
}

@Bean
public FlowBuilderServices flowBuilderServices() {
    return getFlowBuilderServicesBuilder().build();
}
			
```

可配置的服务是`conversion-service``expression-parser``view-factory-creator`。这些服务是通过引用你定义的自定义 bean 来配置的。

例如,在 XML 中:

```
<webflow:flow-builder-services id="flowBuilderServices"
    conversion-service="conversionService"
    expression-parser="expressionParser"
    view-factory-creator="viewFactoryCreator" />

<bean id="conversionService" class="..." />
<bean id="expressionParser" class="..." />
<bean id="viewFactoryCreator" class="..." />
			
```

在 Java 中:

```
@Bean
public FlowBuilderServices flowBuilderServices() {
    return getFlowBuilderServicesBuilder()
            .setConversionService(conversionService())
            .setExpressionParser(expressionParser)
            .setViewFactoryCreator(mvcViewFactoryCreator())
            .build();
}

@Bean
public ConversionService conversionService() {
    // ...
}

@Bean
public ExpressionParser expressionParser() {
    // ...
}

@Bean
public ViewFactoryCreator viewFactoryCreator() {
    // ...
}
			
```

#### 转换-服务

使用`conversion-service`属性定制 Web 流系统使用的`ConversionService`。类型转换用于在流执行期间(例如在处理请求参数、调用操作等时)需要从一种类型转换为另一种类型。支持许多常见的对象类型,如数字、类和枚举。但是,你可能需要为自定义数据类型提供自己的类型转换和格式逻辑。有关如何提供自定义类型转换逻辑的重要信息,请阅读[第 5.7 节,“执行类型转换”](views.html#view-type-conversion)

#### 表达式分析器

使用`expression-parser`属性定制 Web 流系统使用的`ExpressionParser`。默认表达式分析器使用统一的 EL(如果在 Classpath 上可用),否则使用 Spring EL。

#### 视图-工厂-创建者

使用`view-factory-creator`属性定制 Web 流系统使用的`ViewFactoryCreator`。默认的 ViewFactoryCreator 生成 Spring MVC 视图工厂,它能够呈现 JSP、Velocity 和 Freemarker 视图。

可配置设置为`development`。这些设置是可以在流构建过程中应用的全局配置属性。

#### 发展

将此设置为`true`以打开流*发展模式*。开发模式切换到热重载流定义的更改,包括对依赖流资源(如消息包)的更改。

## 10.5.flow-executor 选项

本节将探讨流执行器配置选项。

### 10.5.1.附加流执行侦听器

使用`flow-execution-listeners`元素来注册观察流执行生命周期的侦听器。例如,在 XML 中:

```
<webflow:flow-execution-listeners>
    <webflow:listener ref="securityListener"/>
    <webflow:listener ref="persistenceListener"/>
</webflow:flow-execution-listeners>
			
```

在 Java 中:

```
@Bean
public FlowExecutor flowExecutor() {
    return getFlowExecutorBuilder(flowRegistry())
            .addFlowExecutionListener(securityListener())
            .addFlowExecutionListener(persistenceListener())
            .build();
}
			
```

你也可以将监听器配置为只观察某些流。例如,在 XML 中:

```
<webflow:listener ref="securityListener" criteria="securedFlow1,securedFlow2"/>
			
```

在 Java 中:

```
@Bean
public FlowExecutor flowExecutor() {
    return getFlowExecutorBuilder(flowRegistry())
            .addFlowExecutionListener(securityListener(), "securedFlow1,securedFlow2")
            .build();
}
			
```

### 10.5.2.调优流执行持久性

使用`flow-execution-repository`元素调优流执行持久性设置。例如,在 XML 中:

```
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
    <webflow:flow-execution-repository max-executions="5" max-execution-snapshots="30" />
</webflow:flow-executor>
			
```

在 Java 中:

```
@Bean
public FlowExecutor flowExecutor() {
    return getFlowExecutorBuilder(flowRegistry())
            .setMaxFlowExecutions(5)
            .setMaxFlowExecutionSnapshots(30)
            .build();
}
			
```

#### 最大处决

调整`max-executions`属性,以限制每个用户可以创建的流执行数量会话。当超过最大执行次数时,删除最老的执行。

|[[note](images/note.png)|Note|
|:--------------------------------------------------------------------------------------------------------:|:---|
|`max-executions`属性是每个用户会话,即它在任何流定义的实例之间工作。|    |

#### max-execution-snapshots

调整`max-execution-snapshots`属性,以限制每个流执行可以获取的历史快照的数量。要禁用快照,请将该值设置为 0.要启用无限数量的快照,请将该值设置为-1.

|[[note](images/note.png)|Note|
|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:---|
|历史快照启用浏览器后退按钮支持。<br/>当快照被禁用时,按下浏览器后退按钮将不起作用。<br/>它将导致使用指向尚未记录的快照的执行键。|    |