SpringBoot状态机
状态机优势1、状态机建立的控制中心是跟外界低耦合的,通过event通信;2、控制中心所有的状态都是预设好的,不会超预料;3、状态的跳转都是有设定控制条件的,会按照预设的转移路径运动;4、状态机还非常容易的扩展和变更,支持因业务的发展而变更或扩展复杂业务流程。Spring Boot StateMachine实现1、加入依赖<dependency><groupId>org.sp
·
状态机优势
1、状态机建立的控制中心是跟外界低耦合的,通过event通信;
2、控制中心所有的状态都是预设好的,不会超预料;
3、状态的跳转都是有设定控制条件的,会按照预设的转移路径运动;
4、状态机还非常容易的扩展和变更,支持因业务的发展而变更或扩展复杂业务流程。
Spring Boot StateMachine实现
1、加入依赖
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-core</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
2、定义状态枚举和事件枚举
public enum States {
UNPAID, // 待支付
WAITING_FOR_RECEIVE, // 待收货
DONE // 结束
}
public enum Events {
PAY, // 支付
RECEIVE // 收货
}
3、完成状态机配置:状态机的初始状态和所有状态机的转移规则
@Configuration
//启用状态机功能
@EnableStateMachine
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<States, Events> {
private Logger logger = LoggerFactory.getLogger(getClass());
@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){
logger.info("订单创建,待支付");
return;
}
if(transition.getSource().getId() == States.UNPAID
&& transition.getTarget().getId() == States.WAITING_FOR_RECEIVE){
logger.info("用户完成支付,待收货");
return;
}
if(transition.getSource().getId() == States.WAITING_FOR_RECEIVE
&& transition.getTarget().getId() == States.DONE){
logger.info("用户已收货,订单完成");
}
}
};
}
}
4、创建应用主类来完成整个流程:
package com.lyd;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.statemachine.StateMachine;
@SpringBootApplication
public class Application implements CommandLineRunner{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Autowired
private StateMachine<States, Events> stateMachine;
@Override
public void run(String... args){
stateMachine.start();
stateMachine.sendEvent(Events.PAY);
stateMachine.sendEvent(Events.RECEIVE);
}
}
整个状态的调度逻辑主要依靠配置方式的定义,而所有的业务逻辑操作都被定义在了状态监听器中,其实状态监听器可以实现的功能远不止上面我们所述的内容,它还有更多的事件捕获
注解监听器
对于状态监听器,Spring StateMachine还提供了优雅的注解配置实现方式,所有StateMachineListener接口中定义的事件都能通过注解的方式来进行配置实现。比如,我们可以将之前实现的状态监听器用注解配置来做进一步的简化。
package com.lyd;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.OnTransitionEnd;
import org.springframework.statemachine.annotation.OnTransitionStart;
import org.springframework.statemachine.annotation.WithStateMachine;
/**
* 该配置实现了com.lyd.StateMachineConfig类中定义的状态机监听器实现。
*/
@WithStateMachine
public class EventConfig {
private Logger logger = LoggerFactory.getLogger(getClass());
@OnTransition(target = "UNPAID")
public void create(){
logger.info("订单创建,待支付");
}
@OnTransition(source = "UNPAID", target = "WAITING_FOR_RECEIVE")
public void pay() {
logger.info("用户完成支付,待收货");
}
@OnTransitionStart(source = "UNPAID", target = "WAITING_FOR_RECEIVE")
public void payStart() {
logger.info("用户完成支付,待收货: start");
}
@OnTransitionEnd(source = "UNPAID", target = "WAITING_FOR_RECEIVE")
public void payEnd() {
logger.info("用户完成支付,待收货: end");
}
@OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE")
public void receive() {
logger.info("用户已收货,订单完成");
}
}
状态机实现原理
更多推荐
已为社区贡献1条内容
所有评论(0)