

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 工作流程实施
<a name="workflowimpl"></a>

要实施工作流程，您可以编写一个实施所需 `@Workflow` 接口的类。例如，可按以下所示实施示例工作流程接口 (`MyWorkflow`)：

```
public class MyWFImpl implements MyWorkflow
{
  MyActivitiesClient client = new MyActivitiesClientImpl();
  @Override
  public void startMyWF(int a, String b){
    Promise<Integer> result = client.activity1();
    client.activity2(result);
  }
  @Override
  public void signal1(int a, int b, String c){
    //Process signal
     client.activity2(a + b);
  }
}
```

此类中的 `@Execute` 方法是工作流程逻辑的入口点。由于框架在处理决策任务时使用重播来重建对象状态，因此会为每个决策任务创建一个新对象。

禁止在 `@Workflow` 接口中的 `@Execute` 方法内使用 `Promise<T>` 作为参数。这样做是因为发出异步调用完全是调用方的决策。工作流程实施本身不依赖于调用是同步的还是异步的。因此，生成的客户端接口具有采用 `Promise<T>` 参数的重载，以便能够异步调用这些方法。

`@Execute` 方法的返回类型只能为 `void` 或 `Promise<T>`。请注意，相应的外部客户端的返回类型为 `void` 而不是 `Promise<>`。由于外部客户端不打算从异步代码中使用，因此外部客户端不会返回`Promise`对象。要获得外部声明的工作流执行的结果，您可以设计工作流，通过活动来更新外部数据存储中的状态。Amazon SWF 的可见性还 APIs 可用于检索工作流程结果以进行诊断。一般而言，不建议您使用可见性 APIs 来检索工作流程执行的结果，因为这些 API 调用可能会受到 Amazon SWF 的限制。可见性 APIs 要求您使用`WorkflowExecution`结构来识别工作流程的执行。您可以通过调用 `getWorkflowExecution` 方法，从生成的工作流程客户端获取此结构。此方法将返回与客户端绑定到的工作流程执行对应的 `WorkflowExecution` 结构。有关可见性的更多详细信息，请参阅 [Amazon 简单工作流程服务 API 参考](https://docs.aws.amazon.com/amazonswf/latest/apireference/) APIs。

在从工作流程实施调用活动时，您应使用生成的活动客户端。同样，要发送信号，请使用生成的工作流程客户端。

## 决策上下文
<a name="workflowimpl.decisioncontext"></a>

当框架执行工作流程代码时，它会提供一个环境上下文。此上下文提供了您可在工作流程实施中访问的上下文特定的功能，例如创建计时器。有关更多信息，请参阅[执行关联](executioncontext.md)部分。

## 公开执行状态
<a name="workflowimpl.executionstate"></a>

Amazon SWF 允许您在工作流历史记录中添加自定义状态。工作流执行所报告的最新状态将通过对 Amazon SWF 服务的可见性调用和 Amazon SWF 控制台返回给您。例如，在订单处理工作流程中，您可以在不同的阶段 (如“已收到订单”、“订单已配送”等) 报告订单状态。在适用于 Java 的 AWS Flow Framework 中，这将通过在工作流接口上使用 `@GetState` 注释进行注释的方法实现。在决策程序处理完决策任务后，它将调用此方法，以便从工作流程实施中获取最新状态。除了可见性调用之外，还可使用生成的外部客户端 (它在内部使用可见性 API 调用) 来检索状态。

以下示例演示了如何设置执行上下文。

```
@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 60,
               defaultTaskStartToCloseTimeoutSeconds = 10)
public interface PeriodicWorkflow {

    @Execute(version = "1.0")
    void periodicWorkflow();

    @GetState
    String getState();
}

@Activities(version = "1.0")
@ActivityRegistrationOptions(defaultTaskScheduleToStartTimeoutSeconds = 300,
                             defaultTaskStartToCloseTimeoutSeconds = 3600)
public interface PeriodicActivity {
    void activity1();

}

public class PeriodicWorkflowImpl implements PeriodicWorkflow {

    private DecisionContextProvider contextProvider
               = new DecisionContextProviderImpl();

    private WorkflowClock clock
               = contextProvider.getDecisionContext().getWorkflowClock();

    private PeriodicActivityClient activityClient
               = new PeriodicActivityClientImpl();

    private String state;

    @Override
    public void periodicWorkflow() {
        state = "Just Started";
        callPeriodicActivity(0);
    }

    @Asynchronous
    private void callPeriodicActivity(int count,
                                      Promise<?>... waitFor)
    {
        if(count == 100) {
            state = "Finished Processing";
            return;
        }

        // call activity
        activityClient.activity1();

        // Repeat the activity after 1 hour.
        Promise<Void> timer = clock.createTimer(3600);
        state = "Waiting for timer to fire. Count = "+count;
        callPeriodicActivity(count+1, timer);
    }

    @Override
    public String getState() {
        return state;
    }
}

public class PeriodicActivityImpl implements PeriodicActivity
{
@Override
      public static void activity1()
   {
      ...
    }
}
```

生成的外部客户端可随时用于检索工作流程执行的最新状态。

```
PeriodicWorkflowClientExternal client
        = new PeriodicWorkflowClientExternalFactoryImpl().getClient();
System.out.println(client.getState());
```

在上述示例中，在各个阶段报告执行状态。当工作流程实例启动时，`periodicWorkflow` 将初始状态报告为“刚刚启动”。之后，每次调用 `callPeriodicActivity` 都会更新工作流程状态。在调用 `activity1` 100 次后，此方法返回并且工作流程实例完成。

## 本地工作流程
<a name="workflowimpl.workflowlocals"></a>

有时，您可能需要在工作流程实施中使用静态变量。例如，您可能需要存储要从工作流程实施中的各个位置 (可能是不同的类) 访问的计数器。但是，您不能依赖工作流程中的静态变量，因为静态变量是跨线程共享的，这是有问题的，因为一个工作线程可能同时在不同的线程上处理不同的决策任务。或者，您可以将此类状态存储在工作流程实施的字段中，但您随后需要传递实施对象。为了满足此需求，框架提供了一个 `WorkflowExecutionLocal<?>` 类。任何需要静态变量 (如语义) 的状态都应通过 `WorkflowExecutionLocal<?>` 在本地保留为实例。您可以声明和使用此类型的静态变量。例如，在以下代码段中，`WorkflowExecutionLocal<String>` 用于存储用户名。

```
public class MyWFImpl implements MyWF {
  public static WorkflowExecutionLocal<String> username
      = new WorkflowExecutionLocal<String>();

  @Override
  public void start(String username){
    this.username.set(username);
    Processor p = new Processor();
    p.updateLastLogin();
    p.greetUser();
   }

  public static WorkflowExecutionLocal<String> getUsername() {
    return username;
  }

  public static void setUsername(WorkflowExecutionLocal<String> username) {
    MyWFImpl.username = username;
  }
}

public class Processor {
  void updateLastLogin(){
    UserActivitiesClient c = new UserActivitiesClientImpl();
    c.refreshLastLogin(MyWFImpl.getUsername().get());
  }
   void greetUser(){
    GreetingActivitiesClient c = new GreetingActivitiesClientImpl();
    c.greetUser(MyWFImpl.getUsername().get());
  }
}
```