Editing pass

I edited for spelling, punctuation, grammar, usage, and corporate voice. I also added leader sentences before all the images and code listings and rewrote for clarity.
This commit is contained in:
Jay Bryant
2019-04-03 09:14:31 -05:00
committed by Janne Valkealahti
parent bd2518cce9
commit 16a2a5389d
10 changed files with 3200 additions and 2475 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +1,32 @@
[[statemachine-faq]]
= FAQ
This chapter tries to give solutions to question user is most likely
to ask.
This chapter answers the questions that Spring Statemachine users most often ask.
== State Changes
.I want to transit to next state automatically
.How can I automatically transit to the next state?
{zwsp} +
You can choose from three approaches:
There are few choices a state machine developer can choose.
* Implement an action and send appropriate event into a state machine
which triggers a transition into a proper target state.
* Define deferred event within a state and before sending an event
send an event which will be deferred and thus causing next
* Implement an action and send an appropriate event to a state machine
to trigger a transition into the proper target state.
* Define a deferred event within a state and, before sending an event,
send another event that is deferred. Doing so causes the next
appropriate state transition when it is more convenient to handle
that event.
* Implement a triggerless transition which will automatically cause
state transition into a next state when state has entry and its
* Implement a triggerless transition, which automatically causes a
state transition into the next state when state is entered and its
actions has been completed.
== Extended State
.How I can initialise variables on state machine start
.How I can initialize variables on state machine start?
{zwsp} +
Important concept in a state machine is that nothing really happens
unless there is a trigger which is causing a state transition which
An important concept in a state machine is that nothing really happens
unless a trigger causes a state transition that
then can fire actions. However, having said that, Spring Statemachine
always have an initial transition when state machine is started. With
this initial transition user can execute a simple action which within
a _StateContext_ can do whatever it likes with an extended state
always has an initial transition when a state machine is started. With
this initial transition, you can run a simple action that, within
a `StateContext`, can do whatever it likes with extended state
variables.

View File

@@ -1,77 +1,83 @@
[[statemachine-getting-started]]
= Getting started
If youre just getting started with Spring Statemachine,
this is the section for you! Here we answer the basic
“what?”, “how?” and “why?” questions. Youll find a gentle
introduction to Spring Statemachine. Well then build our
first Spring Statemachine application, discussing some
If you are just getting started with Spring Statemachine,
this is the section for you! Here, we answer the basic
“`what?`”, “`how?`” and “`why?`” questions. We start with a gentle
introduction to Spring Statemachine. We then build our
first Spring Statemachine application and discuss some
core principles as we go.
== System Requirements
== System Requirement
Spring Statemachine {revnumber} is built and tested with
JDK 8(all artifacts have JDK 7 compatibility) and Spring
Framework {spring-version} and doesn't require any other
JDK 8 (all artifacts have JDK 7 compatibility) and Spring
Framework {spring-version}. It does not require any other
dependencies outside of Spring Framework within its core system.
Other optional parts like <<sm-distributed>> has dependencies to
a `Zookeeper`, while <<statemachine-examples>> has dependencies
to spring-shell and spring-boot which pulls other dependencies
beyond framework itself. Also optional security and data access has
dependencies to _Spring Security_ and _Spring Data Modules_.
Other optional parts (such as <<sm-distributed>>) have dependencies on
Zookeeper, while <<statemachine-examples>> has dependencies
on `spring-shell` and `spring-boot`, which pull other dependencies
beyond the framework itself. Also, the optional security and data access features have
dependencies to on Spring Security and Spring Data modules.
== Modules
The following modules are available for Spring Statemachine.
The following table describes the modules that are available for Spring Statemachine.
|===
|Module |Description
|spring-statemachine-core
|Core system of a Spring Statemachine.
|`spring-statemachine-core`
|The core system of Spring Statemachine.
|spring-statemachine-recipes-common
|Common recipes which doesn't require dependencies outside of a core
|`spring-statemachine-recipes-common`
|Common recipes that do not require dependencies outside of the core
framework.
|spring-statemachine-kryo
|`Kryo` serializers for state machine.
|`spring-statemachine-kryo`
|`Kryo` serializers for Spring Statemachine.
|spring-statemachine-data-common
|`spring-statemachine-data-common`
|Common support module for `Spring Data`.
|spring-statemachine-data-jpa
|`spring-statemachine-data-jpa`
|Support module for `Spring Data JPA`.
|spring-statemachine-data-redis
|`spring-statemachine-data-redis`
|Support module for `Spring Data Redis`.
|spring-statemachine-data-mongodb
|`spring-statemachine-data-mongodb`
|Support module for `Spring Data MongoDB`.
|spring-statemachine-zookeeper
|`Zookeeper` integration for a distributed state machine.
|`spring-statemachine-zookeeper`
|Zookeeper integration for a distributed state machine.
|spring-statemachine-test
|`spring-statemachine-test`
|Support module for state machine testing.
|spring-statemachine-cluster
|`spring-statemachine-cluster`
|Support module for Spring Cloud Cluster.
Note that Spring Cloud Cluster has been superseded by Spring Integration.
|spring-statemachine-uml
|Support module for UI uml modeling with Eclipse Papyrus.
|`spring-statemachine-uml`
|Support module for UI UML modeling with Eclipse Papyrus.
|spring-statemachine-autoconfigure
|Support module for `Spring Boot`.
|`spring-statemachine-autoconfigure`
|Support module for Spring Boot.
|spring-statemachine-bom
|`spring-statemachine-bom`
|Bill of Materials pom.
|spring-statemachine-starter
|`Spring Boot` starter.
|`spring-statemachine-starter`
|Spring Boot starter.
|===
== Using Gradle
Here is a typical `build.gradle` file created by https://start.spring.io:
The following listing shows a typical `build.gradle` file created by choosing various settings at https://start.spring.io:
====
[source,groovy,indent=0,subs="attributes+"]
----
buildscript {
@@ -119,29 +125,29 @@ dependencyManagement {
}
}
----
[NOTE]
====
Replace `0.0.1-SNAPSHOT` with a version you want to use.
====
Having a normal project structure you'd build this with command:
IMPORTANT: Replace `0.0.1-SNAPSHOT` with a version you want to use.
With a normal project structure, you can build this project with the following command:
====
[source,text,indent=0]
----
# ./gradlew clean build
----
Expected Spring Boot packaged fat-jar would be `build/libs/demo-0.0.1-SNAPSHOT.jar`.
[NOTE]
====
You don't need repos `libs-milestone` and `libs-snapshot` for
The expected Spring Boot-packaged fat jar would be `build/libs/demo-0.0.1-SNAPSHOT.jar`.
NOTE: You do not need the`libs-milestone` and `libs-snapshot` repositories for
production development.
====
== Using Maven
Here is a typical `pom.xml` file created by https://start.spring.io:
The following example shows a typical `pom.xml` file, which was created by choosing various options at https://start.spring.io:
====
[source,xml,indent=0,subs="attributes+"]
----
<?xml version="1.0" encoding="UTF-8"?>
@@ -246,30 +252,30 @@ Here is a typical `pom.xml` file created by https://start.spring.io:
</project>
----
[NOTE]
====
Replace `0.0.1-SNAPSHOT` with a version you want to use.
====
Having a normal project structure you'd build this with command:
IMPORTANT: Replace `0.0.1-SNAPSHOT` with a version you want to use.
With a normal project structure, you can build this project with the following command:
====
[source,text,indent=0]
----
# mvn clean package
----
Expected Spring Boot packaged fat-jar would be `target/demo-0.0.1-SNAPSHOT.jar`.
[NOTE]
====
You don't need repos `libs-milestone` and `libs-snapshot` for
The expected Spring Boot-packaged fat-jar would be `target/demo-0.0.1-SNAPSHOT.jar`.
NOTE: You do not need the `libs-milestone` and `libs-snapshot` repositories for
production development.
== Developing Your First Spring Statemachine Application
You can start by creating a simple Spring Boot `Application` class
that implements `CommandLineRunner`. The following example shows how to do so:
====
== Developing your first Spring Statemachine application
Let's start by creating a simple Spring Boot `Application` class
implementing `CommandLineRunner`.
[source,java,indent=0]
----
@SpringBootApplication
@@ -281,8 +287,11 @@ public class Application implements CommandLineRunner {
}
----
====
Add states and events:
Then you need to add states and events, as the following example shows:
====
[source,java,indent=0]
----
public enum States {
@@ -293,8 +302,11 @@ public enum Events {
E1, E2
}
----
====
Add state machine configuration:
Then you need to add state machine configuration, as the following example shows:
====
[source,java,indent=0]
----
@Configuration
@@ -342,8 +354,12 @@ public class StateMachineConfig
}
}
----
====
Implement `CommandLineRunner`, autowire `StateMachine`:
Then you need to implement `CommandLineRunner` and autowire `StateMachine`.
The following example shows how to do so:
====
[source,java,indent=0]
----
@Autowired
@@ -355,18 +371,23 @@ public void run(String... args) throws Exception {
stateMachine.sendEvent(Events.E2);
}
----
====
Depending whether you build your application using `Gradle` or `Maven`
it's run `java -jar build/libs/gs-statemachine-0.1.0.jar` or
`java -jar target/gs-statemachine-0.1.0.jar` respectively.
Depending on whether you build your application with `Gradle` or `Maven`,
you can run it by using `java -jar build/libs/gs-statemachine-0.1.0.jar` or
`java -jar target/gs-statemachine-0.1.0.jar`, respectively.
What is expected for running this command is a normal Spring Boot output
but if you look closely you see lines:
The result of this command should be normal Spring Boot output.
However, you should also find the following lines:
====
[source,text,indent=0]
----
State change to SI
State change to S1
State change to S2
----
====
These lines indicate that the machine you constructed
is moving from one state to another, as it should.

View File

@@ -17,11 +17,19 @@
= Spring Statemachine - Reference Documentation
include::preface.adoc[]
include::introduction.adoc[]
include::getting-started.adoc[]
include::whatsnew.adoc[]
include::sm.adoc[]
include::recipes.adoc[]
include::sm-examples.adoc[]
include::faq.adoc[]
include::appendix.adoc[]

View File

@@ -1,60 +1,62 @@
[[introduction]]
= Introduction
Spring Statemachine(SSM) is a framework for application developers to
use traditional state machine concepts with Spring applications. SSM
aims to provide the following features:
* Easy to use flat one level state machine for simple use cases.
Spring Statemachine (SSM) is a framework that lets application developers
use traditional state machine concepts with Spring applications. SSM
provides the following features:
* Easy-to-use flat (one-level) state machine for simple use cases.
* Hierarchical state machine structure to ease complex state
configuration.
* State machine regions to provide even more complex state
configurations.
* Usage of triggers, transitions, guards and actions.
* Type safe configuration adapter.
* Usage of triggers, transitions, guards, and actions.
* Type-safe configuration adapter.
* State machine event listeners.
* Spring IOC integration to associate beans with a state machine.
* Spring IoC integration to associate beans with a state machine.
Before you continue it's worth to go through appendices <<glossary>>
and <<crashcourse>> to get a generic idea of what state machines are,
mostly because the rest of the documentation expects the reader to be
fairly familiar with state machine concepts.
Before you continue, we recommend going through the appendices <<glossary>>
and <<crashcourse>> to get a generic idea of what state machines are.
The rest of the documentation expects you to be
familiar with state machine concepts.
== Background
State machines are powerful because behaviour is always guaranteed to be
State machines are powerful because their behavior is always guaranteed to be
consistent and relatively easily debugged due to how operational
rules are written in stone when machine is started. The idea is that your
application is and may exist in a finite number of states and then something
happens which takes your application from one state to the next. What
will drive a state machine are triggers, which are either based on
rules are written in stone when a machine is started. The idea is that your
application is now in and may exist in a finite number of states. Then something
happens that takes your application from one state to the next.
A state machine is driven by triggers, which are based on either
events or timers.
It is much easier to design high level logic outside of your
It is much easier to design high-level logic outside of your
application and then interact with a state machine in various
different ways. You can simply interact with a state machine by
sending events, listening to what a state machine does or simply requesting
different ways. You can interact with a state machine by
sending events, listening to what a state machine does, or requesting
the current state.
Traditionally state machines are added to an existing project when
Traditionally, state machines are added to an existing project when
developers realize that the code base is starting to look like a plate
full of spaghetti. Spaghetti code looks like a never ending, hierarchical
structure of IFs, ELSEs and BREAK clauses and probably compilers should
structure of IF, ELSE, and BREAK clauses, and compilers should probably
ask developers to go home when things are starting to look too complex.
== Usage Scenarios
A project is a good candidate to use a state machine if:
A project is a good candidate to use a state machine when:
* The application or part of its structure can be represented as states.
* You can represent the application or part of its structure as states.
* You want to split complex logic into smaller manageable tasks.
* The application is already suffering concurrency issues with i.e.
* The application is already suffering concurrency issues with (for example)
something happening asynchronously.
You are already trying to implement a state machine if:
You are already trying to implement a state machine when you:
* Using boolean flags or enums to model situations.
* Having variables which only have meaning for some part of your
* Use boolean flags or enums to model situations.
* Have variables that have meaning only for some part of your
application lifecycle.
* Looping through if/else structure and checking if a particular flag or
enum is set and then making further exceptions about what to do when certain
combinations of your flags and enums exist or don't exist together.
* Loop through an if-else structure (or, worse, multiple such structures),
check whether a particular flag or
enum is set, and then make further exceptions about what to do when certain
combinations of your flags and enums exist or do not exist.

View File

@@ -1,24 +1,25 @@
[preface]
== Preface
The concept of a state machine is most likely older that any reader
The concept of a state machine is most likely older than any reader
of this reference documentation and definitely older than the Java
language itself. Description of finite automata dates back to 1943
when gentlemen Warren McCulloch and Walter Pitts wrote a paper about
it. Later George H. Mealy presented a state machine concept in 1955
which is known as a Mealy Machine. A year later in 1956 Edward F.
Moore presented another paper which is known as a Moore Machine. If
you've ever read anything about state machines, the names Mealy and Moore
it. Later George H. Mealy presented a state machine concept (known as
a "`Mealy Machine`") in 1955. A year later, in 1956, Edward F.
Moore presented another paper, in which he described what is known as
a "`Moore Machine`". If
you have ever read anything about state machines, the names, Mealy and Moore,
should have popped up at some point.
This reference documentation contains the following parts.
This reference documentation contains the following parts:
<<introduction>> introduction to this reference documentation
<<introduction>> contains introduction to this reference documentation.
<<statemachine>> describes the usage of Spring Statemachine(SSM)
<<statemachine>> describes the usage of Spring Statemachine(SSM).
<<statemachine-examples>> more detailed state machine examples
<<statemachine-examples>> contains more detailed state machine examples.
<<statemachine-faq>> frequently asked questions
<<appendices>> generic info about used material and state machines
<<statemachine-faq>> contains frequently asked questions.
<<appendices>> contains generic information about used material and state machines.

View File

@@ -1,130 +1,145 @@
[[statemachine-recipes]]
= Recipes
This chapter contains documentation for existing built-in state
machine recipes.
What exactly is a recipe? As Spring Statemachine is always going to be
a foundational framework meaning that its core will not have that much
higher level functionality or dependencies outside of a Spring
Framework. Correct usage of a state machine may be a little difficult
time to time and there's always some common use cases how state
machine can be used. Recipe modules are meant to provide a higher
level solutions to these common use cases and also provide examples
beyond samples how framework can be used.
Spring Statemachine is a foundational framework. That is, it does not have much
higher-level functionality or many dependencies beyond Spring Framework.
Consequently, correctly using a state machine may be difficult. To help,
we have created a set of recipe modules that address common use cases.
[NOTE]
====
Recipes are a great way to make external contributions this Spring
Statemachine project. If you're not ready to contribute to the
What exactly is a recipe? A state machine recipe is a module that addresses a common
use case. In essence, a state machine recipe is both an example that we have tried to
make it easy for you to reuse and extend.
NOTE: Recipes are a great way to make external contributions to the Spring
Statemachine project. If you are not ready to contribute to the
framework core itself, a custom and common recipe is a great way to
share functionality among other users.
====
share functionality with other users.
[[statemachine-recipes-persist]]
== Persist
Persist recipe is a simple utility which allows to use a single state
machine instance to persist and update a state of an arbitrary item in
The persist recipe is a simple utility that lets you use a single state
machine instance to persist and update the state of an arbitrary item in
a repository.
Recipes main class is `PersistStateMachineHandler` which assumes user
to do three different things:
The recipe's main class is `PersistStateMachineHandler`, which makes three assumptions:
- An instance of a `StateMachine<String, String>` needs to be used
with a `PersistStateMachineHandler`. States and Events are required
to be type of Strings.
- `PersistStateChangeListener` need to be registered with handler
order to react to persist request.
- Method `handleEventWithState` is used to orchestrate state changes.
* An instance of a `StateMachine<String, String>` needs to be used
with a `PersistStateMachineHandler`. Note that states and Events are required
to be type of `String`.
* `PersistStateChangeListener` needs to be registered with handler
to react to persist request.
* The `handleEventWithState` method is used to orchestrate state changes.
There is a sample demonstrating usage of this recipe at
You can find a sample that shows how to use this recipe at
<<statemachine-examples-persist>>.
[[statemachine-recipes-tasks]]
== Tasks
Tasks recipe is a concept to execute DAG of `Runnable` instances using
a state machine. This recipe has been developed from ideas introduced
in sample <<statemachine-examples-tasks>>.
Generic concept of a state machine is shown below. In this state chart
everything under `TASKS` just shows a generic concept of how a single
task is executed. Because this recipe allows to register deep
hierarchical DAG of tasks, meaning a real state chart would be deep
nested collection of sub-states and regions, there's no need to be
The tasks recipe is a concept to run DAG (Directed Acrylic Graph) of `Runnable` instances that use
a state machine. This recipe has been developed from ideas introduced
in <<statemachine-examples-tasks>> sample.
The next image shows the generic concept of a state machine. In this state chart,
everything under `TASKS` shows a generic concept of how a single
task is executed. Because this recipe lets you register a deep
hierarchical DAG of tasks (meaning a real state chart would be a deeply
nested collection of sub-states and regions), we have no need to be
more precise.
For example if you have only two registered tasks, below state chart
would be correct with `TASK_id` replaced with `TASK_1` and `TASK_2` if
registered tasks ids are `1` and `2`.
For example, if you have only two registered tasks, the following state chart
would be correct when `TASK_id` is replaced with `TASK_1` and `TASK_2` (assuming
the registered tasks IDs are `1` and `2`).
image::images/statechart9.png[width=500]
Executing a `Runnable` may result an error and especially if a complex
DAG of tasks is involved it is desirable that there is a way to handle
tasks execution errors and then having a way to continue execution
without executing already successfully executed tasks. Addition to
this it would be nice if some execution errors can be handled
automatically and as a last fallback, if error can't be handled
automatically, state machine is put into a state where user can handle
Executing a `Runnable` may result an error. Especially if a complex
DAG of tasks is involved, you want to have a way to handle
task execution errors and then have a way to continue execution
without executing already successfully executed tasks. Also,
it would be nice if some execution errors can be handled
automatically. As a last fallback, if an error cannot be handled
automatically, the state machine is put into a state where the user can handle
errors manually.
`TasksHandler` contains a builder method to configure handler instance
and follows a simple builder pattern. This builder can be used to
register `Runnable` tasks, `TasksListener` instances, define
`StateMachinePersist` hook, and setup custom `TaskExecutor` instance.
`TasksHandler` contains a builder method to configure a handler instance
and follows a simple builder pattern. You can use this builder to
register `Runnable` tasks and `TasksListener` instances, define
`StateMachinePersist` hook, and set up custom `TaskExecutor` instance.
Now let's take a simple `Runnable` just doing a simple sleep as shown
below. This is a base of all examples in this chapter.
Now we can take a simple `Runnable` that runs a simple sleep as the following
example shows:
====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetAA]
----
====
To execute multiple `sleepRunnable` tasks just register tasks and
execute `runTasks()` method from `TasksHandler`.
NOTE: The preceding example is the base for all of the examples in this chapter.
To execute multiple `sleepRunnable` tasks, you can register tasks and
execute `runTasks()` method from `TasksHandler`, as the following example shows:
====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetB]
----
====
Order to listen what is happening with a task execution an instance of
a `TasksListener` can be registered with a `TasksHandler`. Recipe
provides an adapter `TasksListenerAdapter` if you don't want to
implement a full interface. Listener provides a various hooks to
listen tasks execution events.
To listen to what is happening with a task execution, you can register an instance of
a `TasksListener` with a `TasksHandler`. This recipe
provides an adapter `TasksListenerAdapter` if you do not want to
implement a full interface. The listener provides a various hooks to
listen tasks execution events. The following example shows the definition of the
`MyTasksListener` class:
====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetAB]
----
====
Listeners can be either registered via a builder or directly with a
`TasksHandler` as shown above.
You can either register listeners by using a builder or register them directly with a
`TasksHandler` as the following example shows:
====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetC]
----
====
Above sample show how to create a deep nested DAG of tasks. Every task
needs to have an unique identifier and optionally as task can be
defined to be a sub-task. Effectively this will create a DAG of tasks.
Every task
needs to have a unique identifier, and (optionally) a task can be
defined to be a sub-task. Effectively, this creates a DAG of tasks.
The following example shows how to create a deep nested DAG of tasks:
====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetD]
----
====
When error happens and a state machine running these tasks goes into a
`ERROR` state, user can call handler methods `fixCurrentProblems` to
reset current state of tasks kept in a state machine extended state
variables. Handler method `continueFromError` can then be used to
instruct state machine to transition from `ERROR` state back to
`READY` state where tasks can be executed again.
When an error happens and the state machine running these tasks goes into an
`ERROR` state, you can call `fixCurrentProblems` handler method to
reset the current state of the tasks kept in the state machine's extended state
variables. You can then use the `continueFromError` handler method to
instruct the state machine to transition from the `ERROR` state back to the
`READY` state, where you can again run tasks.
The following example shows how to do so:
====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetE]
----
====

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,57 +2,62 @@
= What's New
== In 1.1
_Spring Statemachine 1.1_ is focusing on security and a better
interoperability with web applications.
* Comprehensive support for _Spring Security_ is added, <<sm-security>>
Spring Statemachine 1.1 focuses on security and better
interoperability with web applications. It includes the following:
* Comprehensive support for Spring Security has been added. See <<sm-security>>.
* Context integration with `@WithStateMachine' has been greatly
enhanced, <<sm-context>>
* `StateContext` is now a first class citizen with how user can
interact with a State Machine, <<sm-statecontext>>.
* Features around persistence has been enhanced with a build-in
support for redis, <<sm-persist-redis>>.
* New feature helping with persist operations,
enhanced. See <<sm-context>>.
* `StateContext` is now a first class citizen, letting you
interact with a State Machine. See <<sm-statecontext>>.
* Features around persistence have been enhanced with built-in
support for redis. See <<sm-persist-redis>>.
* A new feature helps with persist operations. See
<<sm-persist-statemachinepersister>>.
* Configuration model classes are now a public API.
* New features in timer based events.
* New _Junction_ pseudostate <<statemachine-config-states-junction>>.
* New _Exit Point_ and _Entry Point_ pseudostates <<statemachine-config-states-exitentry>>.
* Configuration model classes are now in a public API.
* New features in timer-based events.
* New `Junction` pseudostate. See <<statemachine-config-states-junction>>.
* New Exit Point and Entry Point pseudostates. See <<statemachine-config-states-exitentry>>.
* Configuration model verifier.
* New samples, <<statemachine-examples-security>>, <<statemachine-examples-eventservice>>.
* UI modeling support using Eclipse Papyrus, <<sm-papyrus>>.
* New samples. See <<statemachine-examples-security>> and <<statemachine-examples-eventservice>>.
* UI modeling support using Eclipse Papyrus. See <<sm-papyrus>>.
== In 1.2
_Spring Statemachine 1.2_ is focusing generic enhancements, better
_UML_ support and integrations with external config repositories.
* Support for UML submachines <<sm-papyrus-submachineref>>
* New _Repository_ abstraction keeping machine configuration in an
external repository <<sm-repository>>
* New support for state actions. <<state-actions>>
* New transition error action concepts. <<statemachine-config-transition-actions-errorhandling>>
* New action error action concepts. <<statemachine-config-state-actions-errorhandling>>
* Initial work for _Spring Boot_ support. <<sm-boot>>
* Support for tracing and monitoring. <<sm-monitoring>>
Spring Statemachine 1.2 focuses on generic enhancements, better
UML support, and integrations with external config repositories.
It includes the following:
* Support for UML sub-machines. See <<sm-papyrus-submachineref>>.
* A new repository abstraction that keeps machine configuration in an
external repository. See <<sm-repository>>.
* New support for state actions. See <<state-actions>>.
* New transition error action concepts. See <<statemachine-config-transition-actions-errorhandling>>.
* New action error concepts. See <<statemachine-config-state-actions-errorhandling>>.
* Initial work for Spring Boot support. See <<sm-boot>>.
* Support for tracing and monitoring. See <<sm-monitoring>>.
=== In 1.2.8
_Spring Statemachine 1.2.8_ contains a bit more functionality normally
not seen in a point release but these changes didn't merit a fork of
_Spring Statemachine 1.3_.
* JPA entity classes have changed table names <<sm-repository-config-jpa>>
* New sample <<statemachine-examples-datapersist>>
* New _Entity_ classes for persistence <<sm-repository-persistence>>
used with <<sm-repository-persistence>>
* Transition conflict policy mentioned in
Spring Statemachine 1.2.8 contains a bit more functionality than normally
not seen in a point release, but these changes did not merit a fork of
Spring Statemachine 1.3. It includes the following:
* JPA entity classes have changed table names. See <<sm-repository-config-jpa>>.
* A new sample. See <<statemachine-examples-datapersist>>.
* New entity classes for persistence. See <<sm-repository-persistence>>.
* Transition conflict policy. See
<<statemachine-config-commonsettings>>
== In 2.0
_Spring Statemachine 2.0_ is focusing on _Spring Boot 2.x_ support.
Spring Statemachine 2.0 focuses on Spring Boot 2.x support.
=== In 2.0.0
* Format of monitoring and tracing has been changed <<sm-boot-monitoring>>
* Module `spring-statemachine-boot` has been renamed to `spring-statemachine-autoconfigure`
Spring Statemachine 2.0.0 includes the following:
* The format of monitoring and tracing has been changed. See <<sm-boot-monitoring>>.
* The `spring-statemachine-boot` module has been renamed to `spring-statemachine-autoconfigure`.