多媒体教学网站开发的一般步骤,wordpress 插件手册,wordpress添加友链申请,网站建设合同是否属于技术服务合同1.什么是状态机 
(1). 什么是状态 
先来解释什么是“状态”#xff08; State #xff09;。现实事物是有不同状态的#xff0c;例如一个自动门#xff0c;就有 open 和 closed 两种状态。我们通常所说的状态机是有限状态机#xff0c;也就是被描述的事物的状态的数量是有…1.什么是状态机 
(1). 什么是状态 
先来解释什么是“状态” State 。现实事物是有不同状态的例如一个自动门就有 open 和 closed 两种状态。我们通常所说的状态机是有限状态机也就是被描述的事物的状态的数量是有限个例如自动门的状态就是两个 open 和 closed 。  状态机也就是 State Machine 不是指一台实际机器而是指一个数学模型。说白了一般就是指一张状态转换图。例如根据自动门的运行规则我们可以抽象出下面这么一个图。 
自动门有两个状态open 和 closed closed 状态下如果读取开门信号那么状态就会切换为 open 。open 状态下如果读取关门信号状态就会切换为 closed 。 
状态机的全称是有限状态自动机自动两个字也是包含重要含义的。给定一个状态机同时给定它的当前状态以及输入那么输出状态时可以明确的运算出来的。例如对于自动门给定初始状态 closed 给定输入“开门”那么下一个状态时可以运算出来的。 
这样状态机的基本定义我们就介绍完毕了。重复一下状态机是有限状态自动机的简称是现实事物运行规则抽象而成的一个数学模型。 
(2).四大概念 
下面来给出状态机的四大概念。 
第一个是 State 状态。一个状态机至少要包含两个状态。例如上面自动门的例子有 open 和 closed 两个状态。 第二个是 Event 事件。事件就是执行某个操作的触发条件或者口令。对于自动门“按下开门按钮”就是一个事件。 第三个是 Action 动作。事件发生以后要执行动作。例如事件是“按开门按钮”动作是“开门”。编程的时候一个 Action一般就对应一个函数。 第四个是 Transition 变换。也就是从一个状态变化为另一个状态。例如“开门过程”就是一个变换。 
(3).状态机 
有限状态机Finite-state machine,FSM又称有限状态自动机简称状态机是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。 
FSM是一种算法思想简单而言有限状态机由一组状态、一个初始状态、输入和根据输入及现有状态转换为下一个状态的转换函数组成。 
其作用主要是描述对象在它的生命周期内所经历的状态序列以及如何响应来自外界的各种事件。 
2.状态机图 
做需求时需要了解以下六种元素起始、终止、现态、次态目标状态、动作、条件我们就可以完成一个状态机图了 
以订单为例以从待支付状态转换为待发货状态为例  ①现态是指当前所处的状态。待支付 ②条件又称为“事件”当一个条件被满足将会触发一个动作或者执行一次状态的迁移。支付事件 ③动作条件满足后执行的动作。动作执行完毕后可以迁移到新的状态也可以仍旧保持原状态。动作不是必需的当条件满足后也可以不执行任何动作直接迁移到新状态。状态转换为待发货 ④次态条件满足后要迁往的新状态。“次态”是相对于“现态”而言的“次态”一旦被激活就转变成新的“现态”了。 
3.spring statemachine 
(1).状态机spring statemachine 概述 
Spring Statemachine是应用程序开发人员在Spring应用程序中使用状态机概念的框架 
Spring Statemachine旨在提供以下功能 
1.易于使用的扁平单级状态机用于简单的使用案例。 2.分层状态机结构以简化复杂的状态配置。 3.状态机区域提供更复杂的状态配置。 4.使用触发器转换警卫和操作。 5.键入安全配置适配器。 6.生成器模式用于在Spring Application上下文之外使用的简单实例化通常用例的食谱 7.基于Zookeeper的分布式状态机 8.状态机事件监听器。 9.UML Eclipse Papyrus建模。 10.将计算机配置存储在永久存储中。 11.Spring IOC集成将bean与状态机关联起来。 
状态机功能强大因为行为始终保证一致使调试相对容易。这是因为操作规则是在机器启动时写成的。这个想法是你的应用程序可能存在于有限数量的状态中某些预定义的触发器可以将你的应用程序从一个状态转移到另一个状态。此类触发器可以基于事件或计时器。 
在应用程序之外定义高级逻辑然后依靠状态机来管理状态要容易得多。您可以通过发送事件侦听更改或仅请求当前状态来与状态机进行交互。 
(2).快速开始 
以订单状态扭转的例子为例 
表结构设计如下 
CREATE TABLE tb_order (id bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 主键ID,order_code varchar(128) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 订单编码,status smallint(3) DEFAULT NULL COMMENT 订单状态,name varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 订单名称,price decimal(12,2) DEFAULT NULL COMMENT 价格,delete_flag tinyint(2) NOT NULL DEFAULT 0 COMMENT 删除标记0未删除  1已删除,create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 创建时间,update_time timestamp NOT NULL DEFAULT 0000-00-00 00:00:00 COMMENT 更新时间,create_user_code varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 创建人,update_user_code varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 更新人,version int(11) NOT NULL DEFAULT 0 COMMENT 版本号,remark varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 备注,PRIMARY KEY (id)) ENGINEInnoDB AUTO_INCREMENT6 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin COMMENT订单表;/*Data for the table tb_order */insert  into tb_order(id,order_code,status,name,price,delete_flag,create_time,update_time,create_user_code,update_user_code,version,remark) values (2,A111,1,A,22.00,0,2022-10-15 16:14:11,2022-10-02 21:29:14,zhangsan,zhangsan,0,NULL),(3,A111,1,订单A,22.00,0,2022-10-02 21:53:13,2022-10-02 21:29:14,zhangsan,zhangsan,0,NULL),(4,A111,1,订单A,22.00,0,2022-10-02 21:53:13,2022-10-02 21:29:14,zhangsan,zhangsan,0,NULL),(5,A111,1,订单A,22.00,0,2022-10-03 09:08:30,2022-10-02 21:29:14,zhangsan,zhangsan,0,NULL);1引入依赖 !-- redis持久化状态机 --dependencygroupIdorg.springframework.statemachine/groupIdartifactIdspring-statemachine-redis/artifactIdversion1.2.9.RELEASE/version/dependency!--状态机--dependencygroupIdorg.springframework.statemachine/groupIdartifactIdspring-statemachine-starter/artifactIdversion2.0.1.RELEASE/version/dependency2定义状态机状态和事件 
状态枚举 
/**
* author芋道源码
*/
public enum OrderStatus {// 待支付待发货待收货已完成WAIT_PAYMENT(1, 待支付),WAIT_DELIVER(2, 待发货),WAIT_RECEIVE(3, 待收货),FINISH(4, 已完成);private Integer key;private String desc;OrderStatus(Integer key, String desc) {this.key  key;this.desc  desc;}public Integer getKey() {return key;}public String getDesc() {return desc;}public static OrderStatus getByKey(Integer key) {for (OrderStatus e : values()) {if (e.getKey().equals(key)) {return e;}}throw new RuntimeException(enum not exists.);}}事件 
/**
* author芋道源码
*/
public enum OrderStatusChangeEvent {// 支付发货确认收货PAYED, DELIVERY, RECEIVED;
}3定义状态机规则和配置状态机 ConfigurationEnableStateMachine(name  orderStateMachine)public class OrderStateMachineConfig extends StateMachineConfigurerAdapterOrderStatus, OrderStatusChangeEvent {/*** 配置状态** param states* throws Exception*/public void configure(StateMachineStateConfigurerOrderStatus, OrderStatusChangeEvent states) throws Exception {states.withStates().initial(OrderStatus.WAIT_PAYMENT).states(EnumSet.allOf(OrderStatus.class));}/*** 配置状态转换事件关系** param transitions* throws Exception*/public void configure(StateMachineTransitionConfigurerOrderStatus, OrderStatusChangeEvent transitions) throws Exception {transitions//支付事件:待支付-》待发货.withExternal().source(OrderStatus.WAIT_PAYMENT).target(OrderStatus.WAIT_DELIVER).event(OrderStatusChangeEvent.PAYED).and()//发货事件:待发货-》待收货.withExternal().source(OrderStatus.WAIT_DELIVER).target(OrderStatus.WAIT_RECEIVE).event(OrderStatusChangeEvent.DELIVERY).and()//收货事件:待收货-》已完成.withExternal().source(OrderStatus.WAIT_RECEIVE).target(OrderStatus.FINISH).event(OrderStatusChangeEvent.RECEIVED);}}配置持久化 /*** author芋道源码*/ ConfigurationSlf4jpublic class PersistE, S {/*** 持久化到内存map中** return*/Bean(name  stateMachineMemPersister)public static StateMachinePersister getPersister() {return new DefaultStateMachinePersister(new StateMachinePersist() {Overridepublic void write(StateMachineContext context, Object contextObj) throws Exception {log.info(持久化状态机,context:{},contextObj:{}, JSON.toJSONString(context), JSON.toJSONString(contextObj));map.put(contextObj, context);}Overridepublic StateMachineContext read(Object contextObj) throws Exception {log.info(获取状态机,contextObj:{}, JSON.toJSONString(contextObj));StateMachineContext stateMachineContext  (StateMachineContext) map.get(contextObj);log.info(获取状态机结果,stateMachineContext:{}, JSON.toJSONString(stateMachineContext));return stateMachineContext;}private Map map  new HashMap();});}Resourceprivate RedisConnectionFactory redisConnectionFactory;/*** 持久化到redis中在分布式系统中使用** return*/Bean(name  stateMachineRedisPersister)public RedisStateMachinePersisterE, S getRedisPersister() {RedisStateMachineContextRepositoryE, S repository  new RedisStateMachineContextRepository(redisConnectionFactory);RepositoryStateMachinePersist p  new RepositoryStateMachinePersist(repository);return new RedisStateMachinePersister(p);}}4业务系统 
controller /*** author芋道源码*/ RestControllerRequestMapping(/order)public class OrderController {Resourceprivate OrderService orderService;/*** 根据id查询订单** return*/RequestMapping(/getById)public Order getById(RequestParam(id) Long id) {//根据id查询订单Order order  orderService.getById(id);return order;}/*** 创建订单** return*/RequestMapping(/create)public String create(RequestBody Order order) {//创建订单orderService.create(order);return sucess;}/*** 对订单进行支付** param id* return*/RequestMapping(/pay)public String pay(RequestParam(id) Long id) {//对订单进行支付orderService.pay(id);return success;}/*** 对订单进行发货** param id* return*/RequestMapping(/deliver)public String deliver(RequestParam(id) Long id) {//对订单进行确认收货orderService.deliver(id);return success;}/*** 对订单进行确认收货** param id* return*/RequestMapping(/receive)public String receive(RequestParam(id) Long id) {//对订单进行确认收货orderService.receive(id);return success;}}servie /*** author芋道源码*/ Service(orderService)Slf4jpublic class OrderServiceImpl extends ServiceImplOrderMapper, Order implements OrderService {Resourceprivate StateMachineOrderStatus, OrderStatusChangeEvent orderStateMachine;Resourceprivate StateMachinePersisterOrderStatus, OrderStatusChangeEvent, String stateMachineMemPersister;Resourceprivate OrderMapper orderMapper;/*** 创建订单** param order* return*/public Order create(Order order) {order.setStatus(OrderStatus.WAIT_PAYMENT.getKey());orderMapper.insert(order);return order;}/*** 对订单进行支付** param id* return*/public Order pay(Long id) {Order order  orderMapper.selectById(id);log.info(线程名称{},尝试支付订单号{} ,Thread.currentThread().getName() , id);if (!sendEvent(OrderStatusChangeEvent.PAYED, order)) {log.error(线程名称{},支付失败, 状态异常订单信息{}, Thread.currentThread().getName(), order);throw new RuntimeException(支付失败, 订单状态异常);}return order;}/*** 对订单进行发货** param id* return*/public Order deliver(Long id) {Order order  orderMapper.selectById(id);log.info(线程名称{},尝试发货订单号{} ,Thread.currentThread().getName() , id);if (!sendEvent(OrderStatusChangeEvent.DELIVERY, order)) {log.error(线程名称{},发货失败, 状态异常订单信息{}, Thread.currentThread().getName(), order);throw new RuntimeException(发货失败, 订单状态异常);}return order;}/*** 对订单进行确认收货** param id* return*/public Order receive(Long id) {Order order  orderMapper.selectById(id);log.info(线程名称{},尝试收货订单号{} ,Thread.currentThread().getName() , id);if (!sendEvent(OrderStatusChangeEvent.RECEIVED, order)) {log.error(线程名称{},收货失败, 状态异常订单信息{}, Thread.currentThread().getName(), order);throw new RuntimeException(收货失败, 订单状态异常);}return order;}/*** 发送订单状态转换事件* synchronized修饰保证这个方法是线程安全的** param changeEvent* param order* return*/private synchronized boolean sendEvent(OrderStatusChangeEvent changeEvent, Order order) {boolean result  false;try {//启动状态机orderStateMachine.start();//尝试恢复状态机状态stateMachineMemPersister.restore(orderStateMachine, String.valueOf(order.getId()));Message message  MessageBuilder.withPayload(changeEvent).setHeader(order, order).build();result  orderStateMachine.sendEvent(message);//持久化状态机状态stateMachineMemPersister.persist(orderStateMachine, String.valueOf(order.getId()));} catch (Exception e) {log.error(订单操作失败:{}, e);} finally {orderStateMachine.stop();}return result;}}监听状态的变化 /*** author芋道源码*/     Component(orderStateListener)WithStateMachine(name  orderStateMachine)Slf4jpublic class OrderStateListenerImpl {Resourceprivate OrderMapper orderMapper;OnTransition(source  WAIT_PAYMENT, target  WAIT_DELIVER)public void payTransition(MessageOrderStatusChangeEvent message) {Order order  (Order) message.getHeaders().get(order);log.info(支付状态机反馈信息{},  message.getHeaders().toString());//更新订单order.setStatus(OrderStatus.WAIT_DELIVER.getKey());orderMapper.updateById(order);//TODO 其他业务}OnTransition(source  WAIT_DELIVER, target  WAIT_RECEIVE)public void deliverTransition(MessageOrderStatusChangeEvent message) {Order order  (Order) message.getHeaders().get(order);log.info(发货状态机反馈信息{},  message.getHeaders().toString());//更新订单order.setStatus(OrderStatus.WAIT_RECEIVE.getKey());orderMapper.updateById(order);//TODO 其他业务}OnTransition(source  WAIT_RECEIVE, target  FINISH)public void receiveTransition(MessageOrderStatusChangeEvent message) {Order order  (Order) message.getHeaders().get(order);log.info(确认收货状态机反馈信息{},  message.getHeaders().toString());//更新订单order.setStatus(OrderStatus.FINISH.getKey());orderMapper.updateById(order);//TODO 其他业务}}(3).测试验证 
1验证业务 新增一个订单 http://localhost:8084/order/create  对订单进行支付 http://localhost:8084/order/pay?id2  对订单进行发货 http://localhost:8084/order/deliver?id2  对订单进行确认收货 http://localhost:8084/order/receive?id2  正常流程结束。如果对一个订单进行支付了再次进行支付则会报错http://localhost:8084/order/pay?id2  
报错如下 2验证持久化 内存 
使用内存持久化类持久化 
/*** author芋道源码*/ Resourceprivate StateMachinePersisterOrderStatus, OrderStatusChangeEvent, String stateMachineMemPersister;/*** 发送订单状态转换事件* synchronized修饰保证这个方法是线程安全的** param changeEvent* param order* return*/private synchronized boolean sendEvent(OrderStatusChangeEvent changeEvent, Order order) {boolean result  false;try {//启动状态机orderStateMachine.start();//尝试恢复状态机状态stateMachineMemPersister.restore(orderStateMachine, String.valueOf(order.getId()));Message message  MessageBuilder.withPayload(changeEvent).setHeader(order, order).build();result  orderStateMachine.sendEvent(message);//持久化状态机状态stateMachineMemPersister.persist(orderStateMachine, String.valueOf(order.getId()));} catch (Exception e) {log.error(订单操作失败:{}, e);} finally {orderStateMachine.stop();}return result;}redis持久化 
引入依赖 
!-- redis持久化状态机 --
dependencygroupIdorg.springframework.statemachine/groupIdartifactIdspring-statemachine-redis/artifactIdversion1.2.9.RELEASE/version
/dependency配置yaml 
spring:redis:database: 0host: localhostjedis:pool:max-active: 8max-idle: 8max-wait: min-idle: 0password: port: 6379timeout: 0使用redis持久化类持久化 /*** author芋道源码*/ Resourceprivate StateMachinePersisterOrderStatus, OrderStatusChangeEvent, String stateMachineRedisPersister;/*** 发送订单状态转换事件* synchronized修饰保证这个方法是线程安全的** param changeEvent* param order* return*/private synchronized boolean sendEvent(OrderStatusChangeEvent changeEvent, Order order) {boolean result  false;try {//启动状态机orderStateMachine.start();//尝试恢复状态机状态stateMachineRedisPersister.restore(orderStateMachine, String.valueOf(order.getId()));Message message  MessageBuilder.withPayload(changeEvent).setHeader(order, order).build();result  orderStateMachine.sendEvent(message);//持久化状态机状态stateMachineRedisPersister.persist(orderStateMachine, String.valueOf(order.getId()));} catch (Exception e) {log.error(订单操作失败:{}, e);} finally {orderStateMachine.stop();}return result;}https://mp.weixin.qq.com/s/flRS7bYcRrKi3wjulaqCmQ 文章转载自: http://www.morning.ymwnc.cn.gov.cn.ymwnc.cn http://www.morning.sfhjx.cn.gov.cn.sfhjx.cn http://www.morning.chhhq.cn.gov.cn.chhhq.cn http://www.morning.bkxnp.cn.gov.cn.bkxnp.cn http://www.morning.qtqjx.cn.gov.cn.qtqjx.cn http://www.morning.xhjjs.cn.gov.cn.xhjjs.cn http://www.morning.1000sh.com.gov.cn.1000sh.com http://www.morning.dwwlg.cn.gov.cn.dwwlg.cn http://www.morning.ygkq.cn.gov.cn.ygkq.cn http://www.morning.rwzc.cn.gov.cn.rwzc.cn http://www.morning.wkmpx.cn.gov.cn.wkmpx.cn http://www.morning.mldrd.cn.gov.cn.mldrd.cn http://www.morning.ydnxm.cn.gov.cn.ydnxm.cn http://www.morning.cykqg.cn.gov.cn.cykqg.cn http://www.morning.tkhyk.cn.gov.cn.tkhyk.cn http://www.morning.vibwp.cn.gov.cn.vibwp.cn http://www.morning.lfdzr.cn.gov.cn.lfdzr.cn http://www.morning.wlxfj.cn.gov.cn.wlxfj.cn http://www.morning.ljbch.cn.gov.cn.ljbch.cn http://www.morning.gbyng.cn.gov.cn.gbyng.cn http://www.morning.ljllt.cn.gov.cn.ljllt.cn http://www.morning.bsbcp.cn.gov.cn.bsbcp.cn http://www.morning.lkfsk.cn.gov.cn.lkfsk.cn http://www.morning.fgwzl.cn.gov.cn.fgwzl.cn http://www.morning.mdwlg.cn.gov.cn.mdwlg.cn http://www.morning.ntgjm.cn.gov.cn.ntgjm.cn http://www.morning.znnsk.cn.gov.cn.znnsk.cn http://www.morning.rxnxl.cn.gov.cn.rxnxl.cn http://www.morning.skrrq.cn.gov.cn.skrrq.cn http://www.morning.gwwky.cn.gov.cn.gwwky.cn http://www.morning.hrpmt.cn.gov.cn.hrpmt.cn http://www.morning.nmfwm.cn.gov.cn.nmfwm.cn http://www.morning.ddtdy.cn.gov.cn.ddtdy.cn http://www.morning.ktdqu.cn.gov.cn.ktdqu.cn http://www.morning.pcrzf.cn.gov.cn.pcrzf.cn http://www.morning.ltqzq.cn.gov.cn.ltqzq.cn http://www.morning.hpkgm.cn.gov.cn.hpkgm.cn http://www.morning.tsqrc.cn.gov.cn.tsqrc.cn http://www.morning.24vy.com.gov.cn.24vy.com http://www.morning.fwcjy.cn.gov.cn.fwcjy.cn http://www.morning.kqpsj.cn.gov.cn.kqpsj.cn http://www.morning.ptzbg.cn.gov.cn.ptzbg.cn http://www.morning.lsgjf.cn.gov.cn.lsgjf.cn http://www.morning.mpflb.cn.gov.cn.mpflb.cn http://www.morning.qyxnf.cn.gov.cn.qyxnf.cn http://www.morning.yrqb.cn.gov.cn.yrqb.cn http://www.morning.zxhpx.cn.gov.cn.zxhpx.cn http://www.morning.zrmxp.cn.gov.cn.zrmxp.cn http://www.morning.rqbr.cn.gov.cn.rqbr.cn http://www.morning.qjrjs.cn.gov.cn.qjrjs.cn http://www.morning.pshpx.cn.gov.cn.pshpx.cn http://www.morning.htsrm.cn.gov.cn.htsrm.cn http://www.morning.tjwfk.cn.gov.cn.tjwfk.cn http://www.morning.dskzr.cn.gov.cn.dskzr.cn http://www.morning.jtqxs.cn.gov.cn.jtqxs.cn http://www.morning.tkflb.cn.gov.cn.tkflb.cn http://www.morning.ydmml.cn.gov.cn.ydmml.cn http://www.morning.rtbhz.cn.gov.cn.rtbhz.cn http://www.morning.lqljj.cn.gov.cn.lqljj.cn http://www.morning.dxqfh.cn.gov.cn.dxqfh.cn http://www.morning.jwxmn.cn.gov.cn.jwxmn.cn http://www.morning.plpqf.cn.gov.cn.plpqf.cn http://www.morning.xjnjb.cn.gov.cn.xjnjb.cn http://www.morning.yhgbd.cn.gov.cn.yhgbd.cn http://www.morning.rgyts.cn.gov.cn.rgyts.cn http://www.morning.clbgy.cn.gov.cn.clbgy.cn http://www.morning.wpqcj.cn.gov.cn.wpqcj.cn http://www.morning.wmrgp.cn.gov.cn.wmrgp.cn http://www.morning.pgcmz.cn.gov.cn.pgcmz.cn http://www.morning.pbksb.cn.gov.cn.pbksb.cn http://www.morning.nzsx.cn.gov.cn.nzsx.cn http://www.morning.qnxtz.cn.gov.cn.qnxtz.cn http://www.morning.ckcjq.cn.gov.cn.ckcjq.cn http://www.morning.yckwt.cn.gov.cn.yckwt.cn http://www.morning.pszw.cn.gov.cn.pszw.cn http://www.morning.qnrpj.cn.gov.cn.qnrpj.cn http://www.morning.cldgh.cn.gov.cn.cldgh.cn http://www.morning.lwmxk.cn.gov.cn.lwmxk.cn http://www.morning.sqfrg.cn.gov.cn.sqfrg.cn http://www.morning.hgbzc.cn.gov.cn.hgbzc.cn