Spring状态机的方法详解
前言
Spring状态机的作为一套系统,当我们了解到基本概念和电商平台的实例后,我们更需要关注底层的规律,方法,从而丰富我们的知识,其实一切程序最终都归于底层研究,我们要了解每一个方法的使用和出处。这样在具体项目中,我们才能将具体的业务重写。
一、类似于链式编程结构分析
案例一:
@Override
public void configure(StateMachineTransitionConfigurer<States, String> transitions) throws Exception {
//source 源状态 target 目标状态 event 由这个事件触发 withExternal 获取外部转换的配置程序
transitions
.withExternal()
.source(1).target(2).event(click1)
.and()
.withExternal()
.source(2).target(1).event(click2)
}
}
//可以通过click1事件,由状态1变为状态2;通过click2事件,由状态2变为状态1。StateMachineTransitionConfigurer配置接口从而实现不同类型的转换。
案例二:
@Configuration
@EnableStateMachine
public class Config
extends EnumStateMachineConfigurerAdapter<States, Events> {
@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
throws Exception {
states
.withStates()
.initial(States.S1, action())
.state(States.S1, action(), null)
.state(States.S2, null, action())
.state(States.S2, action())
.state(States.S3, action(), action());
//将初始状态S1和S2,S3等状态相关联
}
@Bean
public Action<States, Events> action() {
return new Action<States, Events>() {
@Override
public void execute(StateContext<States, Events> context) {
// do things as you like
}
};
}
}
在上面,单个Action被定义为bean操作并与状态S1,S2和S3关联。 还有更多的事情需要更多的澄清:
我们定义了初始状态S1的动作。
我们为状态S1定义了进入动作,并且退出动作为空。
我们为状态S2定义了退出动作,并且将进入动作留空。
我们为状态S2定义了一个单独的状态动作。
我们为状态S3定义了一个单进入动作和退出动作
注意状态S1是如何在initial()和state()函数中使用两次的。 这只有在你想用初始状态定义进入或退出动作时才需要。
二、状态机拦截器
stateMachine.getStateMachineAccessor()
.withRegion().addStateMachineInterceptor(new StateMachineInterceptor<String, String>() {
@Override
public Message<String> preEvent(Message<String> message, StateMachine<String, String> stateMachine) {
return message;
}
@Override
public StateContext<String, String> preTransition(StateContext<String, String> stateContext) {
return stateContext;
}
@Override
public void preStateChange(State<String, String> state, Message<String> message,
Transition<String, String> transition, StateMachine<String, String> stateMachine) {
}
@Override
public StateContext<String, String> postTransition(StateContext<String, String> stateContext) {
return stateContext;
}
@Override
public void postStateChange(State<String, String> state, Message<String> message,
Transition<String, String> transition, StateMachine<String, String> stateMachine) {
}
@Override
public Exception stateMachineError(StateMachine<String, String> stateMachine,
Exception exception) {
return exception;
}
});
拦截器可以用来拦截和停止当前的状态变化或转换逻辑,因为一个状态有着前后状态,因此需要拦截前后状态的变化和转换,在转换时我们要获取上下文;在状态变化时,转换是一种必要的输入。
三、常见方法总结
1.Region<S, E>接口
UUID getUuid();
String getId();
State<S,E> getState();
Collection<State<S, E>> getStates();
Collection<Transition<S,E>> getTransitions();
2.抽象类 Enum.java,实现比较功能和序列化功能
final String name;
3.String.java
boolean startsWith(String prefix)
总结
Spring状态机作为一种状态转换的工具,避免了我们使用if-else结构去转换状态,而且代码的可维护性得到了增强。熟练掌握一块知识,从概念到实例,然后再到具体的模块,深化下来就是底层的方法,作为一名程序员,在如今情况下我们前人已经创建了满足业务需求的代码语言和框架,我们必须熟知其中的方法,才能更好地和我们的业务更好地结合。