Cette fois, j'ai eu l'occasion de vérifier ** spring-statement machine 1.2.12 ** en fonction de mes besoins, j'ai donc écrit un article sur ce que j'avais essayé à ce moment-là.
Fondamentalement, le contenu est un échantillon du document officiel [7. Développement de votre première application Spring Statemachine](https://docs.spring.io/spring-statemachine/docs/2.0.2.RELEASE/reference/htmlsingle/#state -machine-via-builder) est identique à la machine à états.
Cependant, comme l'exemple est principalement une application et une configuration Springboot, cette fois le modèle de générateur "[13.2 State Machine via Builder]" (https://docs.spring.io/spring) qui crée directement une instance de la machine d'état -statemachine / docs / 2.0.2.RELEASE / reference / htmlsingle / # state-machine-via-builder) », nous allons l'implémenter comme une simple application console.
Modifiez settings.xml pour passer par PROXY pour l'obtenir directement à partir du référentiel Maven sur Internet.
<?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>
Créez un projet vierge avec le démarrage rapide de maven.
mvn archetype:generate ^
-DinteractiveMode=false ^
-DarchetypeArtifactId=maven-archetype-quickstart ^
-DgroupId=com.example.statemachie.demo ^
-DartifactId=statemachine-demo
Créez un pom.xml minimal avec spring-statementmachine 1.2.12 dans le projet créé ci-dessus.
<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>
J'ai essayé d'obtenir le fichier jar avec mvn dependency: copy-dependencies -DoutputDirectory = lib
.
Ce n'est pas une tâche nécessaire pour l'implémentation, mais cela a été fait pour comprendre les dépendances.
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
C'est la structure du fichier implémenté (src / main / java).
statemachine-demo\src\main\java
└─com
└─example
└─statemachie
└─demo
App.java
Events.java
SampleListener.java
States.java
Le contenu du fichier implémenté.
7.1. States.java
package com.example.statemachie.demo;
public enum States {
SI, S1, S2
}
State Une simple Enum utilisée comme état de la machine.
7.2. Events.java
package com.example.statemachie.demo;
public enum Events {
E1, E2
}
State Une simple Enum utilisée comme événement pour changer l'état d'une machine.
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());
}
}
C'est une fonction de la machine à ressort.
Un écouteur qui vérifie les changements d'état.
Définissez une classe qui hérite de StateMachineListenerAdapter
.
La méthode stateChanged
est appelée lorsque l'état change, et la méthode ʻeventNotAccepted` est appelée lorsque l'événement n'est pas accepté (l'état défini et l'événement ne sont pas liés, c'est-à-dire un événement invalide).
Cette fois, j'ai remplacé ces deux méthodes pour voir les transitions d'état.
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();
}
}
La méthode buildMachine ()
crée une instance de ʻorg.springframework.statemachine.StateMachine. Ce processus peut être défini dans la configuration Java ou dans un fichier XML, mais cette fois, il est généré à la demande avec le modèle de générateur comme expliqué dans "Introduction". Une fois que vous avez créé une instance de
StateMachine, tout ce que vous avez à faire est de démarrer la machine à états avec la méthode
start () et d'exécuter l'événement avec la méthode
sendEvent () `.
correctStateFlow ()
émet les événements dans le bon ordre que vous définissez, tandis que ʻincorrectStateFlow () `émet les événements dans le mauvais ordre (envoie les événements E2 à Sugu après les initiales). J'ai essayé ceci pour voir ce qui se passe en cas de transition d'événement illégale.
C'est un journal de console lorsque je l'ai déplacé.
State change to SI
10 27, 2018 11:48:33 h org.springframework.statemachine.support.LifecycleObjectSupport start
information: started org.springframework.statemachine.support.DefaultStateMachineExecutor@768debd
10 27, 2018 11:48:33 h 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 h org.springframework.statemachine.support.LifecycleObjectSupport stop
information: stopped org.springframework.statemachine.support.DefaultStateMachineExecutor@768debd
10 27, 2018 11:48:34 h 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 h org.springframework.statemachine.support.LifecycleObjectSupport start
information: started org.springframework.statemachine.support.DefaultStateMachineExecutor@387c703b
10 27, 2018 11:48:34 h org.springframework.statemachine.support.LifecycleObjectSupport start
information: started S2 S1 SI / SI / uuid=d075b6b9-8cf5-49fb-bc8e-226bb19600f2 / id=null
event not accepted : E2
La sortie standard de l'écouteur d'événements et le journal de débogage lorsque les méthodes start ()
et stop ()
sont appelées sont générées.
Lorsque vous démarrez une machine à états avec start ()
, elle passe d'abord à l'état de SI
, qui est l'état initial défini dans initial.
L'exécution de l'événement «E1» alors que l'état est «SI» change l'état en «S1».
L'exécution de l'événement «E2» alors que l'état est «S1» change l'état en «S2».
Même si l'état est «S2», «isComplete ()» renvoie «false» car la machine d'état est active.
ʻIsComplete () renvoie
true parce que quitter la machine d'état avec
stop () `termine la machine d'état.
En raison de la relation entre l'état et l'événement, l'état n'est pas modifié même si vous essayez de créer un état de transition non défini. Dans l'exemple, l'événement «E2» a été exécuté avec l'état «SI» à l'état initial. Le résultat est sorti par l'écouteur d'événements, mais l'événement n'a pas été accepté.
Cette fois, j'ai essayé un échantillon du document officiel de la machine Spring State avec un modèle de constructeur. J'espère que vous avez en quelque sorte compris les grandes lignes de Spring State machine.
Cependant, il semble qu'une vérification supplémentaire soit nécessaire pour utiliser la machine Spring State dans un système réel.
Étant donné que l'état est géré par l'instance de StateMachine
en premier lieu, on ne sait pas comment gérer la transition d'état à long terme (flux d'approbation avec l'approbation de l'utilisateur, etc.).
Les documents sont conservés par REDIS (28.3 Utilisation de Redis) Et des exemples de gestion d'état dans les systèmes Web (47. Event Service) Est répertorié, mais cela n'est pris en charge qu'en modifiant la portée du bean.
Cependant, il était très facile à utiliser, donc j'ai pensé qu'il serait utile de trouver un moyen d'appliquer la machine Spring State.
Recommended Posts