Dieses Mal hatte ich die Möglichkeit, ** spring-statement machine 1.2.12 ** je nach meinen Bedürfnissen zu überprüfen, also schrieb ich einen Artikel über das, was ich damals versuchte.
Grundsätzlich handelt es sich bei dem Inhalt um ein Beispiel des offiziellen Dokuments 7. Entwickeln Ihrer ersten Spring Statemachine-Anwendung -machine-via-builder) ist dasselbe wie die Zustandsmaschine.
Da es sich bei dem Beispiel jedoch hauptsächlich um eine Springboot-Anwendung und -Konfiguration handelt, wird diesmal das Builder-Muster "[13.2 State Machine via Builder]" (https://docs.spring.io/spring) verwendet, das direkt eine Instanz der State Machine erstellt -statemachine / docs / 2.0.2.RELEASE / reference / htmlsingle / # state-machine-via-builder) “werden wir es als einfache Konsolen-App implementieren.
Ändern Sie settings.xml, um PROXY zu durchlaufen und es direkt aus dem Maven-Repository im Internet abzurufen.
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<proxies>
<proxy>
<active>true</active>
<protocol>http</protocol>
<host>127.0.0.1</host>
<port>8080</port>
<username>xxxxxx</username>
<password>password</password>
<nonProxyHosts>10.*</nonProxyHosts>
</proxy>
</proxies>
</settings>
Erstellen Sie ein leeres Projekt mit dem Schnellstart von maven.
mvn archetype:generate ^
-DinteractiveMode=false ^
-DarchetypeArtifactId=maven-archetype-quickstart ^
-DgroupId=com.example.statemachie.demo ^
-DartifactId=statemachine-demo
Erstellen Sie mit spring-statementmachine 1.2.12 in dem oben erstellten Projekt eine minimale pom.xml.
<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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.statemachie.demo</groupId>
<artifactId>statemachine-demo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>statemachine-demo</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- spring-statemachine -->
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-core</artifactId>
<version>1.2.12.RELEASE</version>
</dependency>
</dependencies>
<!-- java8 -->
<properties>
<java.version>1.8</java.version>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${java.version}</maven.compiler.source>
</properties>
</project>
Ich habe versucht, die JAR-Datei mit mvn dependency: copy-dependencies -DoutputDirectory = lib
abzurufen.
Es ist keine notwendige Aufgabe für die Implementierung, aber es wurde getan, um die Abhängigkeiten zu verstehen.
commons-logging-1.2.jar
junit-3.8.1.jar
spring-aop-4.3.3.RELEASE.jar
spring-beans-4.3.3.RELEASE.jar
spring-context-4.3.3.RELEASE.jar
spring-core-4.3.3.RELEASE.jar
spring-expression-4.3.3.RELEASE.jar
spring-messaging-4.3.3.RELEASE.jar
spring-statemachine-core-1.2.12.RELEASE.jar
spring-tx-4.3.3.RELEASE.jar
Dies ist die Struktur der implementierten Datei (src / main / java).
statemachine-demo\src\main\java
└─com
└─example
└─statemachie
└─demo
App.java
Events.java
SampleListener.java
States.java
Der Inhalt der implementierten Datei.
7.1. States.java
package com.example.statemachie.demo;
public enum States {
SI, S1, S2
}
Status Eine einfache Aufzählung, die als Status der Maschine verwendet wird.
7.2. Events.java
package com.example.statemachie.demo;
public enum Events {
E1, E2
}
Status Eine einfache Aufzählung, die als Ereignis zum Ändern des Status einer Maschine verwendet wird.
7.3. SampleListener.java
package com.example.statemachie.demo;
import org.springframework.messaging.Message;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.state.State;
public class SampleListener extends
StateMachineListenerAdapter<States, Events> {
@Override
public void stateChanged(State<States, Events> from,
State<States, Events> to) {
System.out.println("State change to " + to.getId());
}
@Override
public void eventNotAccepted(Message<Events> event) {
System.out.println("event not accepted : " + event.getPayload());
}
}
Es ist eine Funktion der Federzustandsmaschine. Ein Listener, der nach Statusänderungen sucht. Definieren Sie eine Klasse, die von StateMachineListenerAdapter erbt. Die Methode "stateChanged" wird aufgerufen, wenn der Status geändert wird, und die Methode "eventNotAccepted" wird aufgerufen, wenn das Ereignis nicht akzeptiert wird (der definierte Status und das Ereignis sind nicht miteinander verbunden, dh ein ungültiges Ereignis). Dieses Mal habe ich diese beiden Methoden überschrieben, um die Zustandsübergänge zu sehen.
7.4. App.java
package com.example.statemachie.demo;
import java.util.EnumSet;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.config.StateMachineBuilder;
import org.springframework.statemachine.config.StateMachineBuilder.Builder;
public class App {
public static void main(String[] args) {
correctStateFlow();
System.out.println("-----------------------");
incorrectStateFlow();
}
private static void correctStateFlow() {
StateMachine<States, Events> stateMachine = null;
try {
stateMachine = buildMachine();
} catch (Exception e) {
e.printStackTrace();
}
stateMachine.start();
stateMachine.sendEvent(Events.E1);
stateMachine.sendEvent(Events.E2);
System.out.println("isComplete() before call stop : "
+ stateMachine.isComplete());
stateMachine.stop();
System.out.println("isComplete() after call stop : "
+ stateMachine.isComplete());
}
private static void incorrectStateFlow() {
StateMachine<States, Events> stateMachine = null;
try {
stateMachine = buildMachine();
} catch (Exception e) {
e.printStackTrace();
}
stateMachine.start();
stateMachine.sendEvent(Events.E2);
}
private static StateMachine<States, Events> buildMachine() throws Exception {
Builder<States, Events> builder = StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial(States.SI) // set initial state
.states(EnumSet.allOf(States.class));
builder.configureTransitions()
.withExternal() // add SI -(E1)-> S1
.source(States.SI).target(States.S1).event(Events.E1)
.and()
.withExternal() // add S1 -(E2)-> S2
.source(States.S1).target(States.S2).event(Events.E2);
SampleListener sampleLister = new SampleListener();
builder.configureConfiguration()
.withConfiguration()
.listener(sampleLister); // set listener
return builder.build();
}
}
Die Methode "buildMachine ()" erstellt eine Instanz von "org.springframework.statemachine.StateMachine". Dieser Prozess kann in einer Java-Konfiguration oder einer XML-Datei definiert werden, diesmal wird er jedoch bei Bedarf mit dem Builder-Muster generiert, wie in "Einführung" erläutert. Nachdem Sie eine Instanz von "StateMachine" erstellt haben, müssen Sie lediglich die Zustandsmaschine mit der Methode "start ()" starten und das Ereignis mit der Methode "sendEvent ()" ausführen.
rectStateFlow ()
gibt Ereignisse in der von Ihnen definierten Reihenfolge aus, währendfalseStateFlow ()
Ereignisse in der falschen Reihenfolge ausgibt (gibt E2-Ereignisse nach den Initialen an Sugu aus). Ich habe dies versucht, um zu sehen, was im Falle eines illegalen Ereignisübergangs passiert.
Es ist ein Konsolenprotokoll, als ich es tatsächlich verschoben habe.
State change to SI
10 27, 2018 11:48:33 Uhr org.springframework.statemachine.support.LifecycleObjectSupport start
Information: started org.springframework.statemachine.support.DefaultStateMachineExecutor@768debd
10 27, 2018 11:48:33 Uhr org.springframework.statemachine.support.LifecycleObjectSupport start
Information: started S2 S1 SI / SI / uuid=af9655e4-645d-4dae-9f69-fd0514cd3a9a / id=null
State change to S1
State change to S2
isComplete() before call stop : false
10 27, 2018 11:48:34 Uhr org.springframework.statemachine.support.LifecycleObjectSupport stop
Information: stopped org.springframework.statemachine.support.DefaultStateMachineExecutor@768debd
10 27, 2018 11:48:34 Uhr org.springframework.statemachine.support.LifecycleObjectSupport stop
Information: stopped S2 S1 SI / / uuid=af9655e4-645d-4dae-9f69-fd0514cd3a9a / id=null
isComplete() after call stop : true
-----------------------
State change to SI
10 27, 2018 11:48:34 Uhr org.springframework.statemachine.support.LifecycleObjectSupport start
Information: started org.springframework.statemachine.support.DefaultStateMachineExecutor@387c703b
10 27, 2018 11:48:34 Uhr org.springframework.statemachine.support.LifecycleObjectSupport start
Information: started S2 S1 SI / SI / uuid=d075b6b9-8cf5-49fb-bc8e-226bb19600f2 / id=null
event not accepted : E2
Die vom Ereignis-Listener ausgegebene Standardausgabe und das Debug-Protokoll beim Aufruf der Methoden start ()
und stop ()
werden ausgegeben.
Wenn Sie eine Zustandsmaschine mit "start ()" starten, wechselt sie zuerst in den Zustand "SI", der der in initial definierte Anfangszustand ist.
Wenn Sie das Ereignis "E1" ausführen, während der Status "SI" ist, wird der Status in "S1" geändert.
Wenn das Ereignis "E2" ausgeführt wird, während der Zustand "S1" ist, wird der Zustand in "S2" geändert.
Selbst wenn der Status "S2" ist, gibt "isComplete ()" false "zurück, da die Statusmaschine aktiv ist.
isComplete ()
gibt true
zurück, da das Beenden der Zustandsmaschine mit stop ()
die Zustandsmaschine beendet.
Aufgrund der Beziehung zwischen Status und Ereignis wird der Status auch dann nicht geändert, wenn Sie versuchen, einen undefinierten Übergangsstatus zu erstellen. In dem Beispiel wurde das Ereignis "E2" mit dem Zustand "SI" im Anfangszustand ausgeführt. Das Ergebnis wird vom Ereignis-Listener ausgegeben, aber das Ereignis wurde nicht akzeptiert.
Diesmal habe ich ein Beispiel des offiziellen Dokuments der Spring State-Maschine mit einem Builder-Muster ausprobiert. Ich hoffe, Sie haben die Umrisse der Spring State-Maschine irgendwie verstanden. Es scheint jedoch, dass eine weitere Überprüfung erforderlich ist, um die Spring State-Maschine in einem tatsächlichen System zu verwenden. Da der Status in erster Linie von der Instanz "StateMachine" verwaltet wird, ist unklar, wie der Statusübergang langfristig verwaltet werden soll (Genehmigungsablauf mit Benutzergenehmigung usw.). Dokumente werden von REDIS beibehalten (28.3 Verwenden von Redis). Und Beispiele für die Statusverwaltung in Websystemen (47. Event Service) Wird aufgelistet, dies wird jedoch nur durch Ändern des Bereichs der Bean unterstützt. Es war jedoch sehr einfach zu bedienen, daher hielt ich es für nützlich, wenn ich einen Weg finden könnte, die Spring State-Maschine anzuwenden.
Recommended Posts