2021-10-09

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结构去转换状态,而且代码的可维护性得到了增强。熟练掌握一块知识,从概念到实例,然后再到具体的模块,深化下来就是底层的方法,作为一名程序员,在如今情况下我们前人已经创建了满足业务需求的代码语言和框架,我们必须熟知其中的方法,才能更好地和我们的业务更好地结合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值