[关闭]
@liuhui0803 2016-06-06T17:12:40.000000Z 字数 2637 阅读 2465

Spring发布1.1版Statemachine框架

数据科学 架构和设计 开发 Spring


摘要:

Spring发布了名为Statemachine的1.1版状态机框架,支持Spring Security、Redis,以及UI建模等功能。

正文:

Spring最近发布了名为Statemachine的1.1版状态机(State machine)框架,该版本新增了如下功能:

根据Spring Statemachine官网介绍,Spring Statemachine“是一种供应用程序开发者在Spring应用程序中使用状态机概念的框架。”Statemachine包含所有常用的核心Spring框架,例如通过Spring的Inversion of Control将Bean关联至有限状态机(Finite State Machine,FSM)的能力。

如果应用程序的状态数量是固定的,并且事件会按照顺序依次在不同状态之间转换,此时为应用程序部署FSM将能带来巨大的价值。Statemachine会使用基于事件或计时器的触发器进行此类转换。

状态和事件可通过String和Enumeration这两种数据类型实现。

例如,我们要开发一个下列状态示意图所示的验票闸机:

此处输入图片的描述

在这个闸机的FSM中,有LOCKED和UNLOCKED两种状态,InsertToken和PassThru两种事件,以及Unlock、Lock、Alarm和Refund四种操作。初始状态LOCKED是由示意图中该状态内部的同心圆代表的。发起InsertToken事件将触发一个Unlock操作,并将状态由LOCKED变为UNLOCKED。一旦处于UNLOCKED状态,将发起PassThru事件并触发Lock操作,随后闸机状态将重新变为LOCKED。Alarm和Refund这两个操作不会导致状态的变化。

为确保这个演示应用尽量简单,其中并未定义具体操作。状态和事件可通过Enumeration实现:

  1. static enum States {
  2. LOCKED,
  3. UNLOCKED
  4. }
  1. static enum Events {
  2. INSERTTOKEN,
  3. PASSTHRU
  4. }

随后需要在StateMachineConfigurer接口中通过定义Spring @Configuration注解上下文(Annotation context)的方式配置状态和转换:

  1. @Configuration
  2. @EnableStateMachine
  3. static class Config extends EnumStateMachineConfigurerAdapter<States,Events> {
  4. @Override
  5. public void configure(StateMachineStateConfigurer<States,Events> states)
  6. throws Exception {
  7. states
  8. .withStates()
  9. .initial(States.LOCKED)
  10. .states(EnumSet.allOf(States.class));
  11. }
  12. @Override
  13. public void configure(StateMachineTransitionConfigurer<States,Events> transitions)
  14. throws Exception {
  15. transitions
  16. .withExternal()
  17. .source(States.LOCKED)
  18. .target(States.UNLOCKED)
  19. .event(Events.InsertToken)
  20. .and()
  21. .withExternal()
  22. .source(States.UNLOCKED)
  23. .target(States.LOCKED)
  24. .event(Events.PassThru);
  25. }
  26. }

@EnableStateMachine注解信号可以通知该上下文闸机可立刻构建完成并启动。

在上述配置中,初始状态LOCKED是通过states.withStates().initial(States.LOCKED)语句定义的。转换则是使用上述代码中所示的source()、target(),以及event()方法定义的。这一系列方法可以用于在FSM中定义所有状态转换。更改状态的标准方法是withExternal()。如果某个操作无需更改状态,例如上述示意图中的Alarm和Refund操作,则可使用withInternal()方法定义。

此外可通过定义StateMachineListener监控闸机FSM的过程:

  1. static class StateMachineListener extends StateMachineListenerAdapter<States,Events> {
  2. @Override
  3. public void stateChanged(State<States,Events> from,State<States,Events> to) {
  4. System.out.println("State changed to: " + to.getId());
  5. }
  6. }

最后可以创建一个StateMachine实例并定义一个run()方法实现监听器,启动闸机FSM,并发送事件。

  1. @Autowired
  2. StateMachine<States,Events> stateMachine;
  3. @Override
  4. public void run(String... args) throws Exception {
  5. StateMachineListener listener = new StateMachineListener();
  6. stateMachine.addStateListener(listener);
  7. stateMachine.start();
  8. stateMachine.sendEvent(Events.InsertToken);
  9. stateMachine.sendEvent(Events.PassThru);
  10. }
  11. public static void main(String[] args) {
  12. SpringApplication.run(org.redlich.statemachine.DemoApplication.class,args);
  13. }

整个项目已发布至Github。详细的参考指南可访问Spring Statemachine网站

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注