BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース SpringがStatemachineフレームワークのバージョン1.1をリリース

SpringがStatemachineフレームワークのバージョン1.1をリリース

原文(投稿日:2016/06/05)へのリンク

Springが先日リリースした,Statemachineというステートマシンフレームワークのバージョン1.1では,次のような新機能が提供されている。

  • Spring Securityのサポート
  • @WithStateMachineによるインテグレーション強化
  • Redisのビルトインサポート
  • UIモデリングのサポート

Webサイトでの説明によれば,Spring Statemachineは,“Springアプリケーションでステートマシンの概念を使用するアプリケーション開発者のためのフレームワーク”である。Statemachineには,SpringのIoC(Inversion of Control)を通じて有限状態機械(FSM, Finite State Machine)にBeanを関連付けるような,通常のSpringフレームワークのコアコンポーネントがすべて含まれている。

FSMのアプリケーションへの展開は,アプリケーションが固定数の状態(ステート)と,状態から状態へと遷移するイベントを持つ場合に有用だ。これらの遷移を発生させるため,ステートマシンは,イベントないしタイマに基づくトリガを使用する。

ステートとイベントは2つのデータ型 - StringとEnumerationを使用して実装することができる。

例えば,次のような状態図を使った回転ドア(turnstile)を実装してみよう。

statemachine-simple.png

この回転ドアFSMのステートはLOCKEDとUNLOCKED,イベントはInsertTokenとPassThru,アクションはUnlock,Lock,Alarm,Refundである。初期状態はLOCKEDで,状態図では2重円で示されている。最初のInsertTokenイベントがUnlockアクションをトリガし,LOCKEDからUNLOCKEDへと状態を遷移させる。UNLOCKED状態になると,PassThruイベントの発行がLockアクションをトリガし,回転ドアのステートは再びLOCKEDへと遷移する。AlarmとRefundアクションは状態変化を起こさない。

デモアプリケーションを簡単にするため,アクションの定義は省略する。ステートとイベントは,Enumerationを使って次のように実装できる。

static enum States {
  LOCKED,
  UNLOCKED
}
static enum Events {
  INSERTTOKEN,
  PASSTHRU
}

次の作業は,Springの@ConfigurationアノテーションコンテキストをStateMachineConfigureインターフェースに定義して,ステートと遷移を設定することだ。

@Configuration
@EnableStateMachine
static class Config extends EnumStateMachineConfigurerAdapter<States,Events> {
  @Override
  public void configure(StateMachineStateConfigurer<States,Events> states)
          throws Exception {
             states
              .withStates()
               .initial(States.LOCKED)
               .states(EnumSet.allOf(States.class));
      }

  @Override
  public void configure(StateMachineTransitionConfigurer<States,Events> transitions)
          throws Exception {
             transitions
              .withExternal()
               .source(States.LOCKED)
               .target(States.UNLOCKED)
               .event(Events.InsertToken)
               .and()
              .withExternal()
               .source(States.UNLOCKED)
               .target(States.LOCKED)
               .event(Events.PassThru);
      }
  }

@EnableStateMachineはこのコンテキストに対して,回転ドアの構築と開始を指示するためのものだ。

この構成では,LOCKが初期状態であることを,states.withStates().initial(States.LOCKED)というステートメントで定義している。状態遷移は上記に示すように,source(), target(), event()といったメソッドを使って定義する。これら一連のメソッドは,FSM内のすべての状態遷移に対して定義されなくてはならない。状態遷移を実行する標準的な方法がwithExternal()メソッドだ。図中のAlarmやRefundのような状態変化を必要としないアクションには,withInternal()メソッドを使用する。

回転ドアFSMの進行状況を監視するためには,StateMachineListenerを定義する。

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

最後にStateMachineのインスタンスを生成して,リスナのインスタンス生成と回転ドアFSMの開始,イベントの送信を行なうrun()メソッドを定義する。

@Autowired
StateMachine<States,Events> stateMachine;
@Override
public void run(String... args) throws Exception {
  StateMachineListener listener = new StateMachineListener();
  stateMachine.addStateListener(listener);
  stateMachine.start();
  stateMachine.sendEvent(Events.InsertToken);
  stateMachine.sendEvent(Events.PassThru);
}

public static void main(String[] args) {
  SpringApplication.run(org.redlich.statemachine.DemoApplication.class,args);
}

このプロジェクト全体はGitHubで公開している。詳細なリファレンスガイドは,Spring StatemachineのWebサイトで見ることができる。

この記事を評価

関連性
形式

この記事に星をつける

おすすめ度
スタイル

BT