Files
spring-statemachine/docs/src/reference/asciidoc/getting-started.adoc
Janne Valkealahti d152bf964b URL Cleanup
- Merge/squash #690 #706 #712
- Exclude all .di, .notation and .uml files whose id's cannot be
  changed.
2019-05-16 08:15:13 +01:00

330 lines
9.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[[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
core principles as we go.
== System Requirements
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
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.
== Modules
The following modules are available for Spring Statemachine.
|===
|Module |Description
|spring-statemachine-core
|Core system of a Spring Statemachine.
|spring-statemachine-recipes-common
|Common recipes which doesn't require dependencies outside of a core
framework.
|spring-statemachine-kryo
|`Kryo` serializers for state machine.
|spring-statemachine-redis
|`Redis` related features for state machine.
|spring-statemachine-zookeeper
|`Zookeeper` integration for a distributed state machine.
|spring-statemachine-test
|Support module for state machine testing.
|spring-statemachine-cluster
|Support module for Spring Cloud Cluster.
|spring-statemachine-uml
|Support module for UI uml modeling.
|===
== Using Gradle
Here is a typical `build.gradle` file:
[source,groovy,indent=0]
----
buildscript {
repositories {
maven { url "https://repo.spring.io/libs-release" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE")
}
}
apply plugin: 'base'
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
version = '0.1.0'
archivesBaseName = 'gs-statemachine'
repositories {
mavenCentral()
maven { url "https://repo.spring.io/libs-release" }
maven { url "https://repo.spring.io/libs-milestone" }
maven { url "https://repo.spring.io/libs-snapshot" }
}
dependencies {
compile("org.springframework.statemachine:spring-statemachine-core:1.0.0.BUILD-SNAPSHOT")
compile("org.springframework.boot:spring-boot-starter:1.2.5.RELEASE")
testCompile("org.springframework.statemachine:spring-statemachine-test:1.0.0.BUILD-SNAPSHOT")
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
----
[NOTE]
====
Replace `1.0.0.BUILD-SNAPSHOT` with a version you want to use.
====
Having a normal project structure you'd build this with command:
[source,text,indent=0]
----
# ./gradlew clean build
----
Expected Spring Boot packaged fat-jar would be `build/libs/gs-statemachine-0.1.0.jar`.
[NOTE]
====
You don't need repos `libs-milestone` and `libs-snapshot` for
production development.
====
== Using Maven
Here is a typical `pom.xml` file:
[source,xml,indent=0]
----
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-statemachine</artifactId>
<version>0.1.0</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-core</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-test</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-release</id>
<url>https://repo.spring.io/libs-release</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>spring-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-release</id>
<url>https://repo.spring.io/libs-release</url>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</project>
----
[NOTE]
====
Replace `1.0.0.BUILD-SNAPSHOT` with a version you want to use.
====
Having a normal project structure you'd build this with command:
[source,text,indent=0]
----
# mvn clean package
----
Expected Spring Boot packaged fat-jar would be `target/gs-statemachine-0.1.0.jar`.
[NOTE]
====
You don't need repos `libs-milestone` and `libs-snapshot` for
production development.
====
== Developing your first Spring Statemachine application
Let's start by creating a simple Spring Boot `Application` class
implementing `CommandLineRunner`.
[source,java,indent=0]
----
@SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
----
Add states and events:
[source,java,indent=0]
----
public enum States {
SI, S1, S2
}
public enum Events {
E1, E2
}
----
Add state machine configuration:
[source,java,indent=0]
----
@Configuration
@EnableStateMachine
public class StateMachineConfig
extends EnumStateMachineConfigurerAdapter<States, Events> {
@Override
public void configure(StateMachineConfigurationConfigurer<States, Events> config)
throws Exception {
config
.withConfiguration()
.autoStartup(true)
.listener(listener());
}
@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
throws Exception {
states
.withStates()
.initial(States.SI)
.states(EnumSet.allOf(States.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
throws Exception {
transitions
.withExternal()
.source(States.SI).target(States.S1).event(Events.E1)
.and()
.withExternal()
.source(States.S1).target(States.S2).event(Events.E2);
}
@Bean
public StateMachineListener<States, Events> listener() {
return new StateMachineListenerAdapter<States, Events>() {
@Override
public void stateChanged(State<States, Events> from, State<States, Events> to) {
System.out.println("State change to " + to.getId());
}
};
}
}
----
Implement `CommandLineRunner`, autowire `StateMachine`:
[source,java,indent=0]
----
@Autowired
private StateMachine<States, Events> stateMachine;
@Override
public void run(String... args) throws Exception {
stateMachine.sendEvent(Events.E1);
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.
What is expected for running this command is a normal Spring Boot output
but if you look closely you see lines:
[source,text,indent=0]
----
State change to SI
State change to S1
State change to S2
----