快速开始

如果您刚刚开始使用Spring StateMachine, 这一部分正是为您准备的!在这里,我们将回答基本的 "what?", "how?" 和 "why?" 问题。我们首先从一个温柔的 介绍开始,逐步讲解Spring StateMachine的基础知识。然后我们将构建我们的第一个Spring StateMachine应用程序,并在过程中讨论一些核心原则。

3. 系统要求

Spring Statemachine 4.0.2-SNAPSHOT 是使用 JDK 8 (所有 artifact 具有 JDK 7 的兼容性) 和 Spring Framework 6.2.10 构建和测试的。它在其核心系统中不需要其他任何外部依赖。spring-doc.cadn.net.cn

其他可选部分(例如使用分布式状态)依赖于Zookeeper,而状态机示例依赖于spring-boot,这会拉取框架本身之外的其他依赖。此外,可选的安全性和数据访问功能依赖于Spring Security和Spring Data模块。spring-doc.cadn.net.cn

4. 模块

The following table describes the modules that are available for Spring Statemachine.spring-doc.cadn.net.cn

模块 描述

spring-statemachine-corespring-doc.cadn.net.cn

Spring 状态机的核心系统。spring-doc.cadn.net.cn

spring-statemachine-recipes-commonspring-doc.cadn.net.cn

不需要核心框架之外的依赖项的常见配方。spring-doc.cadn.net.cn

spring-statemachine-kryospring-doc.cadn.net.cn

Kryo 序列化器用于 Spring StateMachine。spring-doc.cadn.net.cn

spring-statemachine-data-commonspring-doc.cadn.net.cn

Common support module for Spring Data.spring-doc.cadn.net.cn

spring-statemachine-data-jpaspring-doc.cadn.net.cn

支持模块用于Spring Data JPAspring-doc.cadn.net.cn

spring-statemachine-data-redisspring-doc.cadn.net.cn

支持模块用于Spring Data Redisspring-doc.cadn.net.cn

spring-statemachine-data-mongodbspring-doc.cadn.net.cn

支持模块用于Spring Data MongoDBspring-doc.cadn.net.cn

spring-statemachine-zookeeperspring-doc.cadn.net.cn

分布式状态机的Zookeeper集成。spring-doc.cadn.net.cn

spring-statemachine-testspring-doc.cadn.net.cn

支持状态机测试的功能模块。spring-doc.cadn.net.cn

spring-statemachine-clusterspring-doc.cadn.net.cn

Spring Cloud 集群支持模块。 请注意,Spring Cloud Cluster 已被 Spring Integration 所取代。spring-doc.cadn.net.cn

spring-statemachine-umlspring-doc.cadn.net.cn

支持使用 Eclipse Papyrus 进行 UI UML 模型化的设计模块。spring-doc.cadn.net.cn

spring-statemachine-autoconfigurespring-doc.cadn.net.cn

支持模块用于Spring Boot。spring-doc.cadn.net.cn

spring-statemachine-bomspring-doc.cadn.net.cn

Bill of Materials pom.spring-doc.cadn.net.cn

spring-statemachine-starterspring-doc.cadn.net.cn

Spring Bootstarter.spring-doc.cadn.net.cn

5. 使用 Gradle

将以下代码示例展示了通过在 https://start.spring.io 选择各种设置生成的典型 build.gradle 文件:spring-doc.cadn.net.cn

buildscript {
	ext {
		springBootVersion = '3.5.6-SNAPSHOT'
	}
	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'

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
}

repositories {
	mavenCentral()
	maven { url "https://repo.spring.io/snapshot" }
	maven { url "https://repo.spring.io/milestone" }
}


ext {
	springStatemachineVersion = '4.0.2-SNAPSHOT'
}

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 替换为您想使用的版本。

使用正常的项目结构,可以通过以下命令构建此项目:spring-doc.cadn.net.cn

# ./gradlew clean build

The expected Spring Boot-packaged fat jar would be build/libs/demo-0.0.1-SNAPSHOT.jar.spring-doc.cadn.net.cn

您不需要在生产开发中使用`libs-milestone`和libs-snapshot仓库。

6. 使用 Maven

以下示例展示了典型的pom.xml文件,它是通过在https://start.spring.io选择各种选项创建的:spring-doc.cadn.net.cn

<?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.5.6-SNAPSHOT</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.2-SNAPSHOT</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 替换为您想使用的版本。

使用正常的项目结构,可以通过以下命令构建此项目:spring-doc.cadn.net.cn

# mvn clean package

The expected Spring Boot-packaged fat-jar would be target/demo-0.0.1-SNAPSHOT.jar.spring-doc.cadn.net.cn

您不需要在生产开发中使用libs-milestonelibs-snapshot仓库。

7. 开发您的第一个Spring状态机应用程序

您可以从创建一个简单的Spring Boot Application类开始,该类实现CommandLineRunner。以下示例展示了如何做到这一点:spring-doc.cadn.net.cn

@SpringBootApplication
public class Application implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

然后,您需要添加状态和事件,如下例所示:spring-doc.cadn.net.cn

public enum States {
    SI, S1, S2
}

public enum Events {
    E1, E2
}

然后您需要添加状态机配置,如下例所示:spring-doc.cadn.net.cn

@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。以下是一个示例,说明如何做到这一点:spring-doc.cadn.net.cn

@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.jarjava -jar target/gs-statemachine-0.1.0.jar来运行它。spring-doc.cadn.net.cn

此命令的结果应该是正常的 Spring Boot 输出。 但是,您还应该找到以下行:spring-doc.cadn.net.cn

State change to SI
State change to S1
State change to S2

这些行表明您构建的机器 正在从一个状态转换到另一个状态,这是正确的。spring-doc.cadn.net.cn