怎么用ftp上传网站甘肃seo网站
状态机(State Machine)是一种用于描述系统行为的数学模型,广泛应用于计算机科学、工程和自动化等领域。它通过定义系统的状态、事件和转移来模拟系统的动态行为。
基本概念
-
状态(State):系统在某一时刻的特定条件或模式。
-
事件(Event):触发状态转移的外部输入或条件变化。
-
转移(Transition):状态因事件而发生的改变。
-
动作(Action):在状态转移或处于某一状态时执行的操作。
简单点来说就是某一个流程当前状态A->事件1->状态B, 或者状态A->事件2->C的一个流程, 实现起来也是比较简单的
自定义状态机
基本原理就是根据状态机的概念简单实现一下, 根据读取json文件来配置整个流程
状态机配置
@Data
public class StateMachineConfig {/*** 状态机名称(Bean名称)*/private String name;/*** 状态机配置*/private List<Transition> transitions;@Datapublic static class Transition {/*** 当前状态*/private String from;/*** 事件*/private String event;/*** 下一个状态*/private String to;}
}
{"name": "orderProcess","transitions": [{"from": "A","event": "event1","to": "B"},{"from": "A","event": "event2","to": "C"},{"from": "B","event": "event3","to": "C"},{"from": "C","event": "event1","to": "D"}]
}
状态机实例
这个类主要是状态机的实例, 也是实现状态机的核心类, 主要实现为Table类, 简单点说就是两个key确定一个value
/*** 状态机实例类** @author zzt* @version 1.0.0*/
@Slf4j
public class SimpleStateMachine {/*** 状态转换关系*/private final Table<String, String, String> table = HashBasedTable.create();/*** 添加状态转换关系* 该方法用于在状态机中添加从当前状态到新状态的转换关系。转换关系由当前状态、事件和新状态组成。** @param fromState 当前状态,表示转换的起始状态。* @param event 触发状态转换的事件。* @param toState 转换后的新状态。*/public void addTransition(String fromState, String event, String toState) {table.put(fromState, event, toState);}/*** 发送事件以触发状态转换* 此方法根据当前状态和接收到的事件来确定是否需要进行状态转换* 如果当前状态和事件的组合在转换表中定义了状态转换,则执行转换* 否则,输出没有可用转换的消息** @param currentState 当前状态* @param event 触发状态转换的事件* @return 返回新状态*/public String sendEvent(String currentState, String event) {//获取下一个状态String to = table.get(currentState, event);if (StringUtils.isBlank(to)) {log.error("没有可用转换, 请检查配置文件,currentState: [{}], event: [{}]", currentState, event);throw new BusinessException("获取状态异常!");}return to;}
}
状态机工厂
状态机工厂主要就是用来生产状态机实例的, 在实际项目中可能会配置多个流程,因此需要生成多个状态机实例, 当时用时只需要从容器中获取一个实例即可
/*** 状态机实例工厂,负责创建状态机并将其注册到 Spring IOC 容器中** @author zzt* @version 1.0.0*/
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "state-machine")
public class StateMachineFactory {/*** 是否启用状态机*/private Boolean enable = false;/*** 状态机配置文件路径(resources目录下的包)*/private String path = "";private final ApplicationContext applicationContext;/*** 初始化所有状态机并注册到 Spring IOC 容器中*/@Beanpublic void registerStateMachines() {if (enable) {// 获取所有状态机配置List<StateMachineConfig> stateMachineConfigs = StateMachineJsonUtil.readAllJsonFiles(path);// 获取状态机配置名称BeanDefinitionRegistry registry = (BeanDefinitionRegistry) applicationContext.getAutowireCapableBeanFactory();for (StateMachineConfig config : stateMachineConfigs) {//判断是否已经存在Bean名称if (!registry.containsBeanDefinition(config.getName())) {GenericBeanDefinition beanDefinition = new GenericBeanDefinition();beanDefinition.setBeanClass(SimpleStateMachine.class);beanDefinition.setInstanceSupplier(() -> createStateMachine(config));// 使用状态机名称作为 Bean 名称registry.registerBeanDefinition(config.getName(), beanDefinition);} else {log.error("状态机名称:[{}]重复,请检查配置文件!", config.getName());throw new SpringBootPlusException("状态机名称重复,请检查配置文件!");}}}}/*** 创建并配置状态机实例** @param stateMachineConfig 状态机配置* @return 配置好的状态机实例*/private SimpleStateMachine createStateMachine(StateMachineConfig stateMachineConfig) {// 创建状态机并配置SimpleStateMachine stateMachine = new SimpleStateMachine();// 配置状态机的转换规则for (StateMachineConfig.Transition transition : stateMachineConfig.getTransitions()) {stateMachine.addTransition(transition.getFrom(), transition.getEvent(), transition.getTo());}return stateMachine;}
}
读取json文件
/*** 读取 json 文件** @author zzt* @version 1.0.0*/
@Slf4j
public class StateMachineJsonUtil {/*** 读取 resources/path 目录下的所有 .json 文件,并将其解析为 StateMachineConfig 对象的列表。** @param path json文件路径* @return 包含所有解析后的 StateMachineConfig 对象的列表*/public static List<StateMachineConfig> readAllJsonFiles(String path) {ObjectMapper objectMapper = MapperUtils.getInstance();List<StateMachineConfig> stateMachineConfigs = new ArrayList<>();try {ClassPathResource resource = new ClassPathResource(path);File[] files = resource.getFile().listFiles();if (files != null) {// 遍历每个资源文件,将其解析为 StateMachineConfig 对象并添加到列表中for (File file : files) {if (file.exists()) {FileInputStream inputStream = new FileInputStream(file);StateMachineConfig stateMachineConfig = objectMapper.readValue(inputStream, StateMachineConfig.class);stateMachineConfigs.add(stateMachineConfig);}}}} catch (Exception e) {log.error("读取json文件失败,[{}]", e.getMessage(), e);throw new SpringBootPlusException("读取json文件失败");}return stateMachineConfigs;}
}