ows Exception {
states.withStates()
.initial("SI")
.end("SF")
.states(new HashSet<String>(Arrays.asList("S1", "S2", "S3")));
}
/**
* 配置状态节点的流向和事件
* @param transitions the {@link StateMachineTransitionConfigurer}
* @throws Exception
*/
@Override
public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
transitions.withExternal()
.source("SI").target("S1").event("E1").action(initAction())
.and()
.withExternal()
.source("S1").target("S2").event("E2").action(s1Action())
.and()
.withExternal()
.source("S2").target("SF").event("end");
}
/**
* 初始节点到S1
* @return
*/
@Bean
public Action<String, String> initAction() {
return ctx -> log.info("Init Action -- DO: {}", ctx.getTarget().getId());
}
/**
* S1到S2
* @return
*/
@Bean
public Action<String, String> s1Action() {
return ctx -> log.info("S1 Action -- DO: {}", ctx.getTarget().getId());
}
}
4.1.2 状态机状态监听器
@Component
@Slf4j
public class StateMachineListener extends StateMachineListenerAdapter<String, String> {
@Override
public void stateChanged(State from, State to) {
log.info("Transitioned from {} to {}", from == null ? "none" : from.getId(), to.getId());
}
}
4.1.3 状态机配置
@Configuration
@Slf4j
public class StateMachineConfig implements WebMvcConfigurer {
@Resource
private StateMachine<String, String> stateMachine;
@Resource
private StateMachineListener stateMachineListener;
@PostConstruct
public void init() {
stateMachine.addStateListener(stateMachineListener);
}
}
4.1.4 接口示例
4.1.4.1 获取状态机状态列表
@RequestMapping("info")
public String info() {
return StringUtils.collectionToDelimitedString(
stateMachine.getStates()
.stream()
.map(State::getId)
.collect(Collectors.toList()),
",");
}
4.1.4.2 状态机开启
在对Spring状态机进行事件操作之前,必须先开启状态机
@GetMapping("start")
public String start() {
stateMachine.startReactively().block();
return state();
}
4.1.4.3 事件操作
@PostMapping("event")
public String event(@RequestParam(name = "event") String event) {
Message<String> message = MessageBuilder.withPayload(event).build();
return stateMachine.sendEvent(Mono.just(message)).blockLast().getMessage().getPayload();
}
4.1.4.4 获取状态机当前状态
@GetMapping("state")
public String state() {
return Mono.defer(() -> Mono.justOrEmpty(stateMachine.getState().getId())).block();
}
4.1.4.5 一次状态转换的控制台输出
: Completed initialization in 0 ms
: Transitioned from none to SI
: Init Action -- DO: S1
: Transitioned from SI to S1
: S1 Action -- DO: S2
: Transitioned from S1 to S2
: Transitioned from S2 to SF
可以看到,状态从none到SI开始节点,再到S1、S2,然后S2通过E2事件到SF结束节点。
4.2 COLA状态机示例
代码地址:http://xingyun.jd.com/codingRoot/ilt/ilt-component-statemachine/
例如:iTMS中的运输需求单的状态目前有:待分配、已分配、运输中、部分妥投、全部妥投、全部拒收、已取消。
4.2.1 构造状态机
com.jd.ilt.component.statemachine.demo.component.statemachine.TransNeedStateMachine
StateMachineBuilder<TransNeedStatusEnum, TransNeedEventEnum, Cont