入门指南
如果你刚开始接触 Spring Statemachine,那么这部分内容正是为你准备的!在这里,我们回答了基本的“是什么?”、“如何?”和“为什么?”问题。我们首先对 Spring Statemachine 进行一个温和的介绍,然后构建我们的第一个 Spring Statemachine 应用程序,并在过程中讨论一些核心原则。
系统要求
Spring Statemachine 4.0.0 是基于 JDK 8 构建和测试的(所有构件都兼容 JDK 7),并且依赖于 Spring Framework 6.0.14。在其核心系统中,除了 Spring Framework 外,不需要任何其他依赖项。
模块
下表描述了可用于 Spring Statemachine 的模块。
| 模块 | 描述 |
|---|---|
spring-statemachine-core | Spring Statemachine 的核心系统。 |
spring-statemachine-recipes-common | 不需要核心框架之外的依赖的通用配方。 |
spring-statemachine-kryo | Spring Statemachine 的 Kryo 序列化器。 |
spring-statemachine-data-common | Spring Data 的通用支持模块。 |
spring-statemachine-data-jpa | Spring Data JPA 的支持模块。 |
spring-statemachine-data-redis | Spring Data Redis 的支持模块。 |
spring-statemachine-data-mongodb | Spring Data MongoDB 的支持模块。 |
spring-statemachine-zookeeper | 用于分布式状态机的 Zookeeper 集成。 |
spring-statemachine-test | 状态机测试的支持模块。 |
spring-statemachine-cluster | Spring Cloud Cluster 的支持模块。注意,Spring Cloud Cluster 已被 Spring Integration 取代。 |
spring-statemachine-uml | 使用 Eclipse Papyrus 进行 UI UML 建模的支持模块。 |
spring-statemachine-autoconfigure | Spring Boot 的支持模块。 |
spring-statemachine-bom | 材料清单 pom。 |
spring-statemachine-starter | Spring Boot 启动器。 |
使用 Gradle
以下列表展示了一个典型的 build.gradle 文件,该文件是通过在 https://start.spring.io 上选择各种设置生成的:
buildscript {
ext {
springBootVersion = '3.1.6'
}
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
ext {
springStatemachineVersion = '4.0.0'
}
dependencies {
compile('org.springframework.statemachine:spring-statemachine-starter')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports {
mavenBom "org.springframework.statemachine:spring-statemachine-bom:${springStatemachineVersion}"
}
}
将 0.0.1-SNAPSHOT 替换为你想要使用的版本。
在普通的项目结构下,你可以使用以下命令来构建这个项目:
# ./gradlew clean build
预期的 Spring Boot 打包的 fat jar 应该是 build/libs/demo-0.0.1-SNAPSHOT.jar。
你不需要 libs-milestone 和 libs-snapshot 仓库来进行生产开发。
使用 Maven
以下示例展示了一个典型的 pom.xml 文件,该文件是通过在 https://start.spring.io 上选择各种选项创建的:
<?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>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>gs-statemachine</name>
<description>Demo project for Spring Statemachine</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-statemachine.version>4.0.0</spring-statemachine.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-bom</artifactId>
<version>${spring-statemachine.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
将 0.0.1-SNAPSHOT 替换为你想要使用的版本。
在正常的项目结构下,你可以使用以下命令来构建这个项目:
# mvn clean package
预期的 Spring Boot 打包的 fat-jar 应该是 target/demo-0.0.1-SNAPSHOT.jar。
生产开发中不需要使用 libs-milestone 和 libs-snapshot 仓库。
开发你的第一个 Spring Statemachine 应用
你可以从创建一个简单的 Spring Boot Application 类开始,该类实现 CommandLineRunner 接口。以下示例展示了如何做到这一点:
@SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
然后你需要添加状态和事件,如下例所示:
public enum States {
SI, S1, S2
}
public enum Events {
E1, E2
}
然后你需要添加状态机配置,如下例所示:
@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());
}
};
}
}
然后你需要实现 CommandLineRunner 并自动注入 StateMachine。以下示例展示了如何做到这一点:
@Autowired
private StateMachine<States, Events> stateMachine;
@Override
public void run(String... args) throws Exception {
stateMachine.sendEvent(Events.E1);
stateMachine.sendEvent(Events.E2);
}
根据你是使用 Gradle 还是 Maven 构建应用程序,你可以分别通过 java -jar build/libs/gs-statemachine-0.1.0.jar 或 java -jar target/gs-statemachine-0.1.0.jar 来运行它。
该命令的结果应该是正常的 Spring Boot 输出。然而,你还应该找到以下行:
State change to SI
State change to S1
State change to S2
这些行表明你构建的机器正在从一个状态转移到另一个状态,正如预期的那样。