springboot干货——(十九)Spring StateMachine框架实现状态机
2018-03-16 10:54
1186 查看
简介:
Spring StateMachine框架的主要功能是帮助开发者简化状态机的开发过程,让状态机结构更加层次化。
1.老规矩,先上项目结构图
2.新建项目springboot-statemachine,pom.xml如下
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.gwd</groupId>
<artifactId>springboot-statemachine</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-statemachine</name>
<description>Demo project for springboot-statemachine</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</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>2.0.0.RELEASE</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-web</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>
</project>
3.定义场景状态和枚举事件具体如下:
状态:
package com.gwd.pojo;
/**
* @FileName States.java
* @Description:TODO
* @author JackHisen(gu.weidong)
* @version V1.0
* @createtime 2018年3月15日 下午7:31:25
* 修改历史:
* 时间 作者 版本 描述
*====================================================
*
*/
public enum States {
UNPAID, // 待支付
WAITING_FOR_RECEIVE, // 待收货
DONE // 结束
}
事件:
其中共有三个状态(待支付、待收货、结束)以及两个引起状态迁移的事件(支付、收货),其中支付事件PAY会触发状态从待支付UNPAID状态到待收货WAITING_FOR_RECEIVE状态的迁移,而收货事件RECEIVE会触发状态从待收货WAITING_FOR_RECEIVE状态到结束DONE状态的迁移。
4.创建状态机的配置类
package com.gwd.config;
import java.util.EnumSet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.listener.StateMachineListener;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.transition.Transition;
import com.gwd.pojo.Events;
import com.gwd.pojo.States;
/**
* @FileName StateMachineConfig.java
* @Description:TODO
* @author JackHisen(gu.weidong)
* @version V1.0
* @createtime 2018年3月15日 下午7:47:32
* 修改历史:
* 时间 作者 版本 描述
*====================================================
*
*/
@Configuration
@EnableStateMachine
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<States, Events>{
@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
throws Exception {
states
.withStates()
.initial(States.UNPAID)
.states(EnumSet.allOf(States.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
throws Exception {
transitions
.withExternal()
.source(States.UNPAID).target(States.WAITING_FOR_RECEIVE)
.event(Events.PAY)
.and()
.withExternal()
.source(States.WAITING_FOR_RECEIVE).target(States.DONE)
.event(Events.RECEIVE);
}
@Override
public void configure(StateMachineConfigurationConfigurer<States, Events> config)
throws Exception {
config
.withConfiguration()
.listener(listener());
}
@Bean
public StateMachineListener<States, Events> listener() {
return new StateMachineListenerAdapter<States, Events>() {
@Override
public void transition(Transition<States, Events> transition) {
if(transition.getTarget().getId() == States.UNPAID) {
System.out.println("订单创建,待支付");
return;
}
if(transition.getSource().getId() == States.UNPAID
&& transition.getTarget().getId() == States.WAITING_FOR_RECEIVE) {
System.out.println("用户完成支付,待收货");
return;
}
if(transition.getSource().getId() == States.WAITING_FOR_RECEIVE
&& transition.getTarget().getId() == States.DONE) {
System.out.println("用户已收货,订单完成");
return;
}
}
};
}
}
在该类中定义了较多配置内容,下面对这些内容一一说明:
StateMachine状态机功能
5.controller
package com.gwd.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.statemachine.StateMachine;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.gwd.pojo.Events;
import com.gwd.pojo.States;
/**
* @FileName TestController.java
* @Description:TODO
* @author JackHisen(gu.weidong)
* @version V1.0
* @createtime 2018年3月15日 下午8:11:24
* 修改历史:
* 时间 作者 版本 描述
*====================================================
*
*/
@RestController
public class TestController {
@Autowired
private StateMachine<States, Events> stateMachine;
@RequestMapping("/testMachine")
@ResponseBody
public void testMachine() {
stateMachine.start();
stateMachine.sendEvent(Events.PAY);
stateMachine.sendEvent(Events.RECEIVE);
}
}
在
订单创建,待支付
2018-03-16 10:28:57.799 INFO 15368 --- [nio-8080-exec-1] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@7616252a
2018-03-16 10:28:57.800 INFO 15368 --- [nio-8080-exec-1] o.s.s.support.LifecycleObjectSupport : started UNPAID DONE WAITING_FOR_RECEIVE / UNPAID / uuid=a57c0a4b-98b5-4155-b4de-a9d847d96399 / id=null
用户完成支付,待收货
用户已收货,订单完成
其中包括了状态监听器中对各个状态迁移做出的处理。
通过上面的例子,我们可以对如何使用Spring StateMachine做如下小结:
定义状态和事件枚举
为状态机定义使用的所有状态以及初始状态
为状态机定义状态的迁移动作
为状态机指定监听处理器
状态监听器
通过上面的入门示例以及最后的小结,我们可以看到使用Spring
StateMachine来实现状态机的时候,代码逻辑变得非常简单并且具有层次化。整个状态的调度逻辑主要依靠配置方式的定义,而所有的业务逻辑操作都被定义在了状态监听器中,其实状态监听器可以实现的功能远不止上面我们所述的内容,它还有更多的事件捕获,我们可以通过查看
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0 *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.listener;
import org.springframework.messaging.Message;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateContext.Stage;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.Transition;
/**
* {@code StateMachineListener} for various state machine events.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public interface StateMachineListener<S,E> {
/**
* Notified when state is changed.
*
* @param from the source state
* @param to the target state
*/
void stateChanged(State<S,E> from, State<S,E> to);
/**
* Notified when state is entered.
*
* @param state the state
*/
void stateEntered(State<S,E> state);
/**
* Notified when state is exited.
*
* @param state the state
*/
void stateExited(State<S,E> state);
/**
* Notified when event was not accepted.
*
* @param event the event
*/
void eventNotAccepted(Message<E> event);
/**
* Notified when transition happened.
*
* @param transition the transition
*/
void transition(Transition<S, E> transition);
/**
* Notified when transition started.
*
* @param transition the transition
*/
void transitionStarted(Transition<S, E> transition);
/**
* Notified when transition ended.
*
* @param transition the transition
*/
void transitionEnded(Transition<S, E> transition);
/**
* Notified when statemachine starts
*
* @param stateMachine the statemachine
*/
void stateMachineStarted(StateMachine<S, E> stateMachine);
/**
* Notified when statemachine stops
*
* @param stateMachine the statemachine
*/
void stateMachineStopped(StateMachine<S, E> stateMachine);
/**
* Notified when statemachine enters error it can't recover from.
*
* @param stateMachine the state machine
* @param exception the exception
*/
void stateMachineError(StateMachine<S, E> stateMachine, Exception exception);
/**
* Notified when extended state variable is either added, modified or removed.
*
* @param key the variable key
* @param value the variable value
*/
void extendedStateChanged(Object key, Object value);
/**
* Notified on various {@link Stage}s about a {@link StateContext}.
*
* @param stateContext the state context
*/
void stateContext(StateContext<S, E> stateContext);
}
注解监听器
对于状态监听器,Spring
StateMachine还提供了优雅的注解配置实现方式,所有
package com.gwd.config;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;
/**
* @FileName EventConfig.java
* @Description:TODO
* @author JackHisen(gu.weidong)
* @version V1.0
* @createtime 2018年3月16日 上午10:41:20
* 修改历史:
* 时间 作者 版本 描述
*====================================================
*
*/
@WithStateMachine
public class EventConfig {
@OnTransition(target = "UNPAID")
public void create() {
System.out.println("-------订单创建,待支付");
}
@OnTransition(source = "UNPAID", target = "WAITING_FOR_RECEIVE")
public void pay() {
System.out.println("---------用户完成支付,待收货");
}
@OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE")
public void receive() {
System.out.println("---------用户已收货,订单完成");
}
}上述代码实现了与快速入门中定义的
根据实际测试,注解的方式在非注解方式之前运行
2018-03-16 10:50:22.571 INFO 9032 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 16 ms
-------订单创建,待支付
订单创建,待支付
2018-03-16 10:50:22.617 INFO 9032 --- [nio-8080-exec-1] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@37f160cf
2018-03-16 10:50:22.618 INFO 9032 --- [nio-8080-exec-1] o.s.s.support.LifecycleObjectSupport : started DONE WAITING_FOR_RECEIVE UNPAID / UNPAID / uuid=0c1d6a4f-bfd6-4e22-b84e-358e1b6cefb7 / id=null
---------用户完成支付,待收货
用户完成支付,待收货
---------用户已收货,订单完成
用户已收货,订单完成
Spring StateMachine框架的主要功能是帮助开发者简化状态机的开发过程,让状态机结构更加层次化。
1.老规矩,先上项目结构图
2.新建项目springboot-statemachine,pom.xml如下
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.gwd</groupId>
<artifactId>springboot-statemachine</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-statemachine</name>
<description>Demo project for springboot-statemachine</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</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>2.0.0.RELEASE</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-web</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>
</project>
3.定义场景状态和枚举事件具体如下:
状态:
package com.gwd.pojo;
/**
* @FileName States.java
* @Description:TODO
* @author JackHisen(gu.weidong)
* @version V1.0
* @createtime 2018年3月15日 下午7:31:25
* 修改历史:
* 时间 作者 版本 描述
*====================================================
*
*/
public enum States {
UNPAID, // 待支付
WAITING_FOR_RECEIVE, // 待收货
DONE // 结束
}
事件:
package com.gwd.pojo; /** * @FileName Events.java * @Description:TODO * @author JackHisen(gu.weidong) * @version V1.0 * @createtime 2018年3月15日 下午7:39:55 * 修改历史: * 时间 作者 版本 描述 *==================================================== * */ public enum Events { PAY, // 支付 RECEIVE // 收货 }
其中共有三个状态(待支付、待收货、结束)以及两个引起状态迁移的事件(支付、收货),其中支付事件PAY会触发状态从待支付UNPAID状态到待收货WAITING_FOR_RECEIVE状态的迁移,而收货事件RECEIVE会触发状态从待收货WAITING_FOR_RECEIVE状态到结束DONE状态的迁移。
4.创建状态机的配置类
package com.gwd.config;
import java.util.EnumSet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.listener.StateMachineListener;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.transition.Transition;
import com.gwd.pojo.Events;
import com.gwd.pojo.States;
/**
* @FileName StateMachineConfig.java
* @Description:TODO
* @author JackHisen(gu.weidong)
* @version V1.0
* @createtime 2018年3月15日 下午7:47:32
* 修改历史:
* 时间 作者 版本 描述
*====================================================
*
*/
@Configuration
@EnableStateMachine
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<States, Events>{
@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
throws Exception {
states
.withStates()
.initial(States.UNPAID)
.states(EnumSet.allOf(States.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
throws Exception {
transitions
.withExternal()
.source(States.UNPAID).target(States.WAITING_FOR_RECEIVE)
.event(Events.PAY)
.and()
.withExternal()
.source(States.WAITING_FOR_RECEIVE).target(States.DONE)
.event(Events.RECEIVE);
}
@Override
public void configure(StateMachineConfigurationConfigurer<States, Events> config)
throws Exception {
config
.withConfiguration()
.listener(listener());
}
@Bean
public StateMachineListener<States, Events> listener() {
return new StateMachineListenerAdapter<States, Events>() {
@Override
public void transition(Transition<States, Events> transition) {
if(transition.getTarget().getId() == States.UNPAID) {
System.out.println("订单创建,待支付");
return;
}
if(transition.getSource().getId() == States.UNPAID
&& transition.getTarget().getId() == States.WAITING_FOR_RECEIVE) {
System.out.println("用户完成支付,待收货");
return;
}
if(transition.getSource().getId() == States.WAITING_FOR_RECEIVE
&& transition.getTarget().getId() == States.DONE) {
System.out.println("用户已收货,订单完成");
return;
}
}
};
}
}
在该类中定义了较多配置内容,下面对这些内容一一说明:
@EnableStateMachine注解用来启用Spring
StateMachine状态机功能
configure(StateMachineStateConfigurer<States, Events> states)方法用来初始化当前状态机拥有哪些状态,其中
initial(States.UNPAID)定义了初始状态为
UNPAID,
states(EnumSet.allOf(States.class))则指定了使用上一步中定义的所有状态作为该状态机的状态定义。
configure(StateMachineTransitionConfigurer<States, Events> transitions)方法用来初始化当前状态机有哪些状态迁移动作,其中命名中我们很容易理解每一个迁移动作,都有来源状态
source,目标状态
target以及触发事件
event。
configure(StateMachineConfigurationConfigurer<States, Events> config)方法为当前的状态机指定了状态监听器,其中
listener()则是调用了下一个内容创建的监听器实例,用来处理各个各个发生的状态迁移事件。
StateMachineListener<States, Events> listener()方法用来创建
StateMachineListener状态监听器的实例,在该实例中会定义具体的状态迁移处理逻辑,上面的实现中只是做了一些输出,实际业务场景会会有更负责的逻辑,所以通常情况下,我们可以将该实例的定义放到独立的类定义中,并用注入的方式加载进来。
5.controller
package com.gwd.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.statemachine.StateMachine;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.gwd.pojo.Events;
import com.gwd.pojo.States;
/**
* @FileName TestController.java
* @Description:TODO
* @author JackHisen(gu.weidong)
* @version V1.0
* @createtime 2018年3月15日 下午8:11:24
* 修改历史:
* 时间 作者 版本 描述
*====================================================
*
*/
@RestController
public class TestController {
@Autowired
private StateMachine<States, Events> stateMachine;
@RequestMapping("/testMachine")
@ResponseBody
public void testMachine() {
stateMachine.start();
stateMachine.sendEvent(Events.PAY);
stateMachine.sendEvent(Events.RECEIVE);
}
}
在
run函数中,我们定义了整个流程的处理过程,其中
start()就是创建这个订单流程,根据之前的定义,该订单会处于待支付状态,然后通过调用
sendEvent(Events.PAY)执行支付操作,最后通过掉用
sendEvent(Events.RECEIVE)来完成收货操作。在运行了上述程序之后,我们可以在控制台中获得类似下面的输出内容:
订单创建,待支付
2018-03-16 10:28:57.799 INFO 15368 --- [nio-8080-exec-1] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@7616252a
2018-03-16 10:28:57.800 INFO 15368 --- [nio-8080-exec-1] o.s.s.support.LifecycleObjectSupport : started UNPAID DONE WAITING_FOR_RECEIVE / UNPAID / uuid=a57c0a4b-98b5-4155-b4de-a9d847d96399 / id=null
用户完成支付,待收货
用户已收货,订单完成
其中包括了状态监听器中对各个状态迁移做出的处理。
通过上面的例子,我们可以对如何使用Spring StateMachine做如下小结:
定义状态和事件枚举
为状态机定义使用的所有状态以及初始状态
为状态机定义状态的迁移动作
为状态机指定监听处理器
状态监听器
通过上面的入门示例以及最后的小结,我们可以看到使用Spring
StateMachine来实现状态机的时候,代码逻辑变得非常简单并且具有层次化。整个状态的调度逻辑主要依靠配置方式的定义,而所有的业务逻辑操作都被定义在了状态监听器中,其实状态监听器可以实现的功能远不止上面我们所述的内容,它还有更多的事件捕获,我们可以通过查看
StateMachineListener接口来了解它所有的事件定义:
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0 *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.statemachine.listener;
import org.springframework.messaging.Message;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateContext.Stage;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.Transition;
/**
* {@code StateMachineListener} for various state machine events.
*
* @author Janne Valkealahti
*
* @param <S> the type of state
* @param <E> the type of event
*/
public interface StateMachineListener<S,E> {
/**
* Notified when state is changed.
*
* @param from the source state
* @param to the target state
*/
void stateChanged(State<S,E> from, State<S,E> to);
/**
* Notified when state is entered.
*
* @param state the state
*/
void stateEntered(State<S,E> state);
/**
* Notified when state is exited.
*
* @param state the state
*/
void stateExited(State<S,E> state);
/**
* Notified when event was not accepted.
*
* @param event the event
*/
void eventNotAccepted(Message<E> event);
/**
* Notified when transition happened.
*
* @param transition the transition
*/
void transition(Transition<S, E> transition);
/**
* Notified when transition started.
*
* @param transition the transition
*/
void transitionStarted(Transition<S, E> transition);
/**
* Notified when transition ended.
*
* @param transition the transition
*/
void transitionEnded(Transition<S, E> transition);
/**
* Notified when statemachine starts
*
* @param stateMachine the statemachine
*/
void stateMachineStarted(StateMachine<S, E> stateMachine);
/**
* Notified when statemachine stops
*
* @param stateMachine the statemachine
*/
void stateMachineStopped(StateMachine<S, E> stateMachine);
/**
* Notified when statemachine enters error it can't recover from.
*
* @param stateMachine the state machine
* @param exception the exception
*/
void stateMachineError(StateMachine<S, E> stateMachine, Exception exception);
/**
* Notified when extended state variable is either added, modified or removed.
*
* @param key the variable key
* @param value the variable value
*/
void extendedStateChanged(Object key, Object value);
/**
* Notified on various {@link Stage}s about a {@link StateContext}.
*
* @param stateContext the state context
*/
void stateContext(StateContext<S, E> stateContext);
}
注解监听器
对于状态监听器,Spring
StateMachine还提供了优雅的注解配置实现方式,所有
StateMachineListener接口中定义的事件都能通过注解的方式来进行配置实现。比如,我们可以将之前实现的状态监听器用注解配置来做进一步的简化:
package com.gwd.config;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;
/**
* @FileName EventConfig.java
* @Description:TODO
* @author JackHisen(gu.weidong)
* @version V1.0
* @createtime 2018年3月16日 上午10:41:20
* 修改历史:
* 时间 作者 版本 描述
*====================================================
*
*/
@WithStateMachine
public class EventConfig {
@OnTransition(target = "UNPAID")
public void create() {
System.out.println("-------订单创建,待支付");
}
@OnTransition(source = "UNPAID", target = "WAITING_FOR_RECEIVE")
public void pay() {
System.out.println("---------用户完成支付,待收货");
}
@OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE")
public void receive() {
System.out.println("---------用户已收货,订单完成");
}
}上述代码实现了与快速入门中定义的
listener()方法创建的监听器相同的功能,但是由于通过注解的方式配置,省去了原来事件监听器中各种if的判断,使得代码显得更为简洁,拥有了更好的可读性。
根据实际测试,注解的方式在非注解方式之前运行
2018-03-16 10:50:22.571 INFO 9032 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 16 ms
-------订单创建,待支付
订单创建,待支付
2018-03-16 10:50:22.617 INFO 9032 --- [nio-8080-exec-1] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@37f160cf
2018-03-16 10:50:22.618 INFO 9032 --- [nio-8080-exec-1] o.s.s.support.LifecycleObjectSupport : started DONE WAITING_FOR_RECEIVE UNPAID / UNPAID / uuid=0c1d6a4f-bfd6-4e22-b84e-358e1b6cefb7 / id=null
---------用户完成支付,待收货
用户完成支付,待收货
---------用户已收货,订单完成
用户已收货,订单完成
相关文章推荐
- Spring-statemachine fork一个region后不能进入join状态的问题
- Spring Boot干货系列:(七)默认日志框架配置
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
- SpringMVC Mybatis Shiro RestTemplate的实现客户端无状态验证及访问控制【转】
- java计划任务调度框架quartz结合spring实现调度的配置实例代码
- 运用DWR框架实现AJAX并与Spring与struts以及hibernate中的整合
- Winform开发框架中实现信息阅读状态的显示和存储
- 实现类似于Spring的可配置的AOP框架
- 学习笔记--代理与AOP及实现类似SPRING的可配置的AOP框架
- 设计模式C++学习笔记之十九(State状态模式)
- 在Spring Boot框架下使用WebSocket实现消息推送
- 微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务
- 状态模式(state)C++实现
- springboot(十九):使用Spring Boot Actuator监控应用
- SpringSecurity+SpringMVC +Mybatis3.0实现的web小框架
- java基础--实现类似Spring的可配置的aop框架
- 安卓实战开发之CardView的selector及GrideView的item按下状态保留selector(state_activated)的实现
- 尝试用java实现有状态的事件驱动的web开发(view-state)
- 搭建你的Spring.Net+Nhibernate+Asp.Net Mvc 框架 (三)实现数据库接口层和业务逻辑层
- Spring StateMachine 介绍