package com.tuoheng.status.statemachine.manager; import com.tuoheng.status.statemachine.events.Event; import com.tuoheng.status.statemachine.status.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.config.StateMachineFactory; import org.springframework.statemachine.state.State; import org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; /** * 状态机管理器 * 用于管理多个状态机实例,通过ID获取和查询状态机 */ @Component public class StateMachineManager { private static final Logger logger = Logger.getLogger(StateMachineManager.class.getName()); @Autowired private StateMachineFactory stateMachineFactory; // 存储状态机实例的Map,key为状态机ID private final Map> stateMachineMap = new ConcurrentHashMap<>(); /** * 创建或获取状态机实例 * 如果ID对应的状态机不存在,则创建新实例;如果存在,则返回现有实例 * * @param machineId 状态机ID * @return 状态机实例 */ public StateMachine getOrCreateStateMachine(String machineId) { return stateMachineMap.computeIfAbsent(machineId, id -> { logger.info("创建新状态机实例,ID: " + id); StateMachine stateMachine = stateMachineFactory.getStateMachine(id); // 将machineId存储到扩展状态中 stateMachine.getExtendedState().getVariables().put("machineId", id); // 启动状态机 stateMachine.start(); return stateMachine; }); } /** * 获取状态机实例(如果不存在则返回null) * * @param machineId 状态机ID * @return 状态机实例,如果不存在则返回null */ public StateMachine getStateMachine(String machineId) { return stateMachineMap.get(machineId); } /** * 创建新的状态机实例(如果已存在则先停止并移除旧的) * * @param machineId 状态机ID * @return 新创建的状态机实例 */ public StateMachine createStateMachine(String machineId) { // 如果已存在,先停止并移除 StateMachine existing = stateMachineMap.remove(machineId); if (existing != null) { logger.info("停止并移除已存在的状态机,ID: " + machineId); try { existing.stop(); } catch (Exception e) { logger.warning("停止状态机时发生错误: " + e.getMessage()); } } // 创建新实例 logger.info("创建新状态机实例,ID: " + machineId); StateMachine stateMachine = stateMachineFactory.getStateMachine(machineId); stateMachine.getExtendedState().getVariables().put("machineId", machineId); stateMachine.start(); stateMachineMap.put(machineId, stateMachine); return stateMachine; } /** * 获取状态机的当前状态 * * @param machineId 状态机ID * @return 当前状态,如果状态机不存在则返回null */ public Status getCurrentStatus(String machineId) { StateMachine stateMachine = stateMachineMap.get(machineId); if (stateMachine == null) { logger.warning("状态机不存在,ID: " + machineId); return null; } State state = stateMachine.getState(); if (state == null) { return null; } return state.getId(); } /** * 获取状态机的详细信息(包括当前状态和扩展状态) * * @param machineId 状态机ID * @return 状态机信息,如果状态机不存在则返回null */ public StateMachineInfo getStateMachineInfo(String machineId) { StateMachine stateMachine = stateMachineMap.get(machineId); if (stateMachine == null) { return null; } StateMachineInfo info = new StateMachineInfo(); info.setMachineId(machineId); State state = stateMachine.getState(); if (state != null) { info.setCurrentStatus(state.getId()); info.setIsSubState(state.isSubmachineState()); } info.setExtendedState(stateMachine.getExtendedState().getVariables()); // 通过检查状态机是否有状态来判断是否在运行 // Spring StateMachine 3.2.0 没有 isRunning() 方法,使用状态判断 info.setIsRunning(state != null); return info; } /** * 移除状态机实例 * * @param machineId 状态机ID * @return 是否成功移除 */ public boolean removeStateMachine(String machineId) { StateMachine stateMachine = stateMachineMap.remove(machineId); if (stateMachine != null) { logger.info("移除状态机实例,ID: " + machineId); try { stateMachine.stop(); return true; } catch (Exception e) { logger.warning("停止状态机时发生错误: " + e.getMessage()); return false; } } return false; } /** * 检查状态机是否存在 * * @param machineId 状态机ID * @return 是否存在 */ public boolean exists(String machineId) { return stateMachineMap.containsKey(machineId); } /** * 获取所有状态机的ID列表 * * @return 状态机ID集合 */ public java.util.Set getAllMachineIds() { return stateMachineMap.keySet(); } /** * 获取当前管理的状态机数量 * * @return 状态机数量 */ public int getStateMachineCount() { return stateMachineMap.size(); } /** * 清空所有状态机实例 */ public void clearAll() { logger.info("清空所有状态机实例,数量: " + stateMachineMap.size()); for (Map.Entry> entry : stateMachineMap.entrySet()) { try { entry.getValue().stop(); } catch (Exception e) { logger.warning("停止状态机时发生错误,ID: " + entry.getKey() + ", 错误: " + e.getMessage()); } } stateMachineMap.clear(); } /** * 状态机信息类 */ public static class StateMachineInfo { private String machineId; private Status currentStatus; private boolean isSubState; private boolean isRunning; private Map extendedState; // Getters and Setters public String getMachineId() { return machineId; } public void setMachineId(String machineId) { this.machineId = machineId; } public Status getCurrentStatus() { return currentStatus; } public void setCurrentStatus(Status currentStatus) { this.currentStatus = currentStatus; } public boolean isSubState() { return isSubState; } public void setIsSubState(boolean subState) { isSubState = subState; } public boolean isRunning() { return isRunning; } public void setIsRunning(boolean running) { isRunning = running; } public Map getExtendedState() { return extendedState; } public void setExtendedState(Map extendedState) { this.extendedState = extendedState; } @Override public String toString() { return "StateMachineInfo{" + "machineId='" + machineId + '\'' + ", currentStatus=" + currentStatus + ", isSubState=" + isSubState + ", isRunning=" + isRunning + ", extendedState=" + extendedState + '}'; } } }