Spring Statemachine 3.0.0-RC1 发布

发布 | Janne Valkealahti | 2020年12月11日 | ...

是的,我们正在转向响应式编程!

我代表团队和所有贡献者,很高兴地宣布 Spring Statemachine 3.0.0 的第一个候选版本已经发布,您可以从我们的里程碑存储库获取。

此版本的亮点包括:

  • 现在,与状态机一起工作的相关 API 具有响应式方法。
  • 从功能角度来看,此版本与2.2.x2.3.x2.4.x 分支中的内容相同,除了响应式更改。
  • 我们选择与最近发布的 Spring Boot 2.4.1 保持一致。

在内部,一切基本上都是基于响应式概念工作的,同时我们仍然保留旧样式的方法用于阻塞式世界。计划是看看是否以及何时可以从阻塞式世界中逐步淘汰。现在,让我们谈谈新的 API。

在传统的阻塞式世界中,您只需发送一个事件,状态机就会返回一个布尔标志,指示事件是否被接受。

StateMachine<String, String> stateMachine;

boolean accepted = stateMachine.sendEvent("event1");

一件稍微令人烦恼的事情是,您无法区分事件被接受(事件导致转换)、被拒绝(拦截器错误或没有可能的转换)或被延迟(如果机器配置使用延迟事件)的情况。我们选择丰富事件处理方法返回的内容。

StateMachine<String, String> stateMachine;

Mono<StateMachineEventResult<String, String>> result = stateMachine
  .sendEvent(Mono.just(MessageBuilder.withPayload("event1").build()));

result.subscribe();

首先,正如您可能猜到的那样,如果您熟悉 Reactor,那么在您订阅返回的Mono之前,什么也不会发生;其次,Mono 中返回的类型是StateMachineEventResult,其中包含有关事件处理发生情况的更多信息。

那么Flux 呢?简单地传入一个 Flux 并获取一个 Flux,然后您可以使用 Reactor 中的任何方法来处理它!

StateMachine<String, String> stateMachine;

Message<String> message1 = MessageBuilder.withPayload("event1").build();
Message<String> message2 = MessageBuilder.withPayload("event2").build();

Flux<StateMachineEventResult<String, String>> results = stateMachine
  .sendEvents(Flux.just(message1, message2));

results.subscribe();

那么操作呢?因为您主要的工作就是与状态机中的操作打交道。原始的阻塞签名是:

public interface Action<S, E> {
  void execute(StateContext<S, E> context);
}

新的ReactiveAction 只是一个 Java 的Function,类型为StateContext<S, E>Mono<Void>

public interface ReactiveAction<S, E>
  extends Function<StateContext<S, E>, Mono<Void>> {}

这意味着:

class MyAction implements ReactiveAction<String, String> {
  @Override
  public Mono<Void> apply(StateContext<String, String> context) {
      return Mono.empty();
  }
}

配置方式:

@Configuration
@EnableStateMachine
public class StateMachineConfig extends StateMachineConfigurerAdapter<String, String> {

  @Override
  public void configure(StateMachineStateConfigurer<String, String> states)
      throws Exception {
    states
      .withStates()
      .initial("state1")
      .state("state2");
  }

  @Override
  public void configure(StateMachineTransitionConfigurer<String, String> transitions)
      throws Exception {
    transitions
      .withExternal()
        .source("state1").target("state2")
        .actionFunction(context -> Mono.fromRunnable(() -> {
          System.out.println("HI");
        }));
  }
}

或者以普通方式定义Function 作为action

Function<StateContext<String, String>, Mono<Void>> action =
  context -> Mono.empty();

项目页面 | GitHub | 问题 | 文档

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring 在一个简单的订阅中提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部