BT

New Early adopter or innovator? InfoQ has been working on some new features for you. Learn more

Spring Releases Version 1.1 Statemachine Framework

| by Michael Redlich Follow 2 Followers on Jun 05, 2016. Estimated reading time: 2 minutes |

Spring’s recent release of  their state machine framework, dubbed Statemachine version 1.1, offers a host of new features including:

  • Support for Spring Security
  • Enhanced integration with @WithStateMachine
  • Built-in support for Redis
  • Support for UI modeling

According to the Spring Statemachine website, Spring Statemachine “is a framework for application developers to use state machine concepts with Spring applications.” Statemachine includes all of the usual core Spring framework components such as associating beans to a Finite State Machine (FSM) through Spring’s Inversion of Control.

Deploying an FSM in an application is useful where there are a fixed number of states and events that transition from one state to the next.  Statemachine uses triggers based on events or timers to make those transitions.

States and events can be implemented using two data types: String and Enumeration.

As an example, let’s develop a detailed turnstile, with the following state diagram:

statemachine-simple.png

In this turnstile FSM, the states are LOCKED and UNLOCKED, the events are InsertToken and PassThru, and the actions are Unlock, Lock, Alarm, and Refund.  The initial state is LOCKED as denoted in the diagram by the inner concentric circle within that state. Initiating the InsertToken event triggers an Unlock action and changes the state from LOCKED to UNLOCKED.  Once in the UNLOCKED state, initiating the PassThru event triggers the Lock action and the state of the turnstile is transitioned back to the LOCKED state.  The actions, Alarm and Refund, do not cause a change in state.

To keep the demo application simple, actions will not be defined.  States and events will be implemented using Enumeration:

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

The next task is to configure the states and transitions through by defining a Spring @Configuration annotation context in our StateMachineConfigurer interface:

@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);
      }
  }

The @EnableStateMachine annotation signals this context that the turnstile will immediately be built and started.

In this configuration, the initial state, LOCKED, is defined with the statement, states.withStates().initial(States.LOCKED).  Transitions are defined using the methods source(), target(), and event() as shown above.  This series of methods should be defined for all state transitions in an FSM. The method withExternal() is the standard way of changing states.  The method withInternal() would be used if an action does not require a change in state as with Alarm and Refund shown in the diagram.

A StateMachineListener is defined to monitor the turnstile FSM progress:

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());
  }
}

Finally, an instance of StateMachine is created and a run() method is defined to instantiate the listener, start the turnstile FSM, and send events.

@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);
}

The entire project can be found on Github. A detailed reference guide can be found on the Spring Statemachine website.

Rate this Article

Adoption Stage
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

TLA+ by Jean-Jacques Dubray

Dr Lamport provided a much better way to model state machines. I would certainly encourage anyone to read this article.

State machines can be described and manipulated with ordinary, everyday mathematics— that is, with sets, functions, and simple logic.


Petri Nets (the semantics we all learned in school) are somewhat of an approximation: actions do not decide of the resulting state. The connection between action and resulting state is "observed".

Re: Java & Spring passion for abstraction by Oliver Gierke

Did you mean Bytebuddy? bytebuddy.net/#/#helloworld

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

3 Discuss

Login to InfoQ to interact with what matters most to you.


Recover your password...

Follow

Follow your favorite topics and editors

Quick overview of most important highlights in the industry and on the site.

Like

More signal, less noise

Build your own feed by choosing topics you want to read about and editors you want to hear from.

Notifications

Stay up-to-date

Set up your notifications and don't miss out on content that matters to you

BT